📄 opexdaylightsaving.c
字号:
// OPEXdaylightSaving.c
// (C) 2004 Steve Childress stevech@san.rr.com
#include "OPEX.h"
// set time via serial port can alter these
int8_t GMT_offset_standard = -8; // GMT offset hours when in Standard Time
int8_t GMT_offset_now;
// tables of pairs of bytes.
// first 2 are the starting and ending months of DST.
// After those are the dates by year, for start/end day
// in April/Oct for DST in most areas of the US.
#define DSTdates_WRT 4 // data in the table byte 3 et al is 200x and later
const BYTE __attribute__((progmem)) DSTdatesUS_wrt[] =
{ 4,10, 4,31, 3,30, 2,29, 1,28, 6,26, 5,25, 4,31 };
// Same, but for most of the EU, March/Oct
const BYTE __attribute__((progmem)) DSTdatesEU_wrt[] =
{ 3,10, 28,31, 27,30, 26,29, 25,28, 30,26, 29,25, 28,31 };
//////////////////////////////////////////////////////////
// return guess that current GMT_offset_standard time is in the US' rules
// this might need tweaking for special cases (AZ, US territories, Asia).
//
BYTE *DST_table(void)
{
BYTE *p;
switch ( (int)GMT_offset_standard ) {
case 0:
case -1:
case -2:
case -3:
case -4:
p = (BYTE *) &DSTdatesEU_wrt[0]; // Zones in the EU
break;
case -5: // EST
case -6: // CST
case -7: // MST
case -8: // PST
case -9: // Alaska
p = (BYTE *) &DSTdatesUS_wrt[0]; // Zones in the US
break;
default:
p = (BYTE *) &DSTdatesUS_wrt[0]; // Zones in the US
break;
}
return(p);
}
//////////////////////////////////////
void OPEX_daylight_saving_changes_at(BYTE starts, DATE_TIME *t)
{
BYTE i, *p;
p = DST_table(); // determine which TZ table to use
i = 2 + (2 * (t->year - DSTdates_WRT)); // table index for start/end day
if (starts) { // return starting date/time of DST
t->month = PRG_RDB(p+0); // DST starting month
t->day = PRG_RDB(p+i); // DST starting day
}
else { // return ending date/time of DST
t->month = PRG_RDB(p+1); // DST ending month
t->day = PRG_RDB(p+i+1); // DST ending day
}
t->hour = 2;
t->minute = t->second = t->tick = 0;
}
///////////////////////////////////////////////////////
// Return 1 if current date/time is in the daylight saving range
// This code is for most cities in the US and the EU.
// Be sure to change table DSTdates_wrt[] which is compiled for the US rules.
int OPEX_is_daylight_saving(void)
{
int ret;
DATE_TIME t;
ret = 0;
t.year = time.year;
OPEX_daylight_saving_changes_at(1, &t); // get starting date presuming 2AM local
if (OPEX_compare_dt(&time, &t) >= 0) { // time now >= t
OPEX_daylight_saving_changes_at(0, &t); // get ending date of DST presuming 2AM local
if (GMT_offset_standard == GMT_offset_now) // true for standard time mode
--t.hour; // DST ends at 1AM standard time since clock is in that mode
if (OPEX_compare_dt(&time, &t) <= 0) // time now <= end of DST
ret = 1;
}
return(ret);
}
//////////////////////////////////
// Adjust for Daylight Saving start/end
// call at initialization, or any other time, preferrably 2AM on the day of change.
// If called at other times, will correct the clock if change is overdue.
// returns 1 if time was adjusted
// NOTE: Whether or not the clock is already DST adjusted is determined by
// detecting DST yes/no for the clock's date/time versus the retained information
// in GMT_offset_now != GMT_offset_standard - which is essentially a DST flag.
int OPEX_daylight_saving_adjust(void)
{
int ret = 0;
if (OPEX_is_daylight_saving()) { // is current date/time in daylight saving range?
if (GMT_offset_now == GMT_offset_standard) { // is clock in daylighg savings time?
++time.hour; // yes, so clock needs to be changed, spring ahead
GMT_offset_now = GMT_offset_standard + 1;
save_date(); // save to EEPROM
ret = 1;
}
}
else { // current date/time is now standard time
if (GMT_offset_now != GMT_offset_standard) { //
--time.hour; // time change, fall back
GMT_offset_now = GMT_offset_standard;
save_date(); // save to EEPROM
ret = 1;
}
}
return(ret);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -