⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opexdaylightsaving.c

📁 学完单片机就要使用实时系统在单片机上运行
💻 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 + -