- #define FEBRUARY 2
- #define STARTOFTIME 1970
- #define SECDAY 86400L
- #define SECYR (SECDAY * 365)
- #define leapyear(year) ((year) % 4 == 0)
- #define days_in_year(a) (leapyear(a) ? 366 : 365)
- #define days_in_month(a) (month_days[(a) - 1])
- extern _strTime g_SysTime;
- static const u8 MonthDay[2][12] = {
- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //非闰年
- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //闰年
- };
- /*
- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
- */
- /*计算公历*/ //gb 计算星期 2012-04-27 星期五 13:56:10
- static void GregorianDay(_strTime* tm)
- {
- int leapsToDate;
- int lastYear;
- int day;
- int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
- lastYear=tm->tm_year-1;
- /*计算从公元元年到计数的前一年之中一共经历了多少个闰年*/
- leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
- /*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/
- if((tm->tm_year%4==0) &&
- ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
- (tm->tm_mon>2)) {
- /*
- * We are past Feb. 29 in a leap year
- */
- day=1;
- } else {
- day=0;
- }
- day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_day; /*计算从公元元年元旦到计数日期一共有多少天*/
- tm->tm_wday=day%7;
- }
- /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the **n calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
- // u32 mktimev(_strTime *tm)
- uint32_t ap_time_date2sec(_strTime *Time)
- {
- // char Temp = 0;
- _strTime tmp = {0,0,0,0,0,0,0};
- // u32 lTime = 0;
- // tmp = g_SysTime;
- tmp.tm_sec = Time->tm_sec;
- tmp.tm_min = Time->tm_min;
- tmp.tm_hour = Time->tm_hour;
- tmp.tm_day = Time->tm_day;
- tmp.tm_mon = Time->tm_mon;
- tmp.tm_year = Time->tm_year;
- // if (0 >= (int) (tm.tm_mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- if (0 >= (s8) (tmp.tm_mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- tmp.tm_mon += 12; /* Puts Feb last since it has leap day */
- tmp.tm_year -= 1;
- }
- return (((
- (u32) (tmp.tm_year/4 - tmp.tm_year/100 + tmp.tm_year/400 + 367*tmp.tm_mon/12 + tmp.tm_day) +
- tmp.tm_year*365 - 719499
- )*24 + tmp.tm_hour /* now have hours */
- )*60 + tmp.tm_min /* now have minutes */
- )*60 + tmp.tm_sec; /* finally seconds */
- }
- /******************************************************************************
- *Function : ap_sec2date
- *CreatDate: 2012-04-27 星期五 14:11:31
- *Author :
- *
- *Descrip : 将秒转换为日期
- *Input : tim - 秒,tm - 日期结构体指针,用于保存转换结果
- *Output :
- *
- *Note :
- ******************************************************************************/
- void ap_time_sec2date(u32 tim, _strTime * tm)
- {
- register u32 i;
- register long hms, day;
- day = tim / SECDAY;
- hms = tim % SECDAY;
- /* Hours, minutes, seconds are easy */
- tm->tm_hour = hms / 3600;
- tm->tm_min = (hms % 3600) / 60;
- tm->tm_sec = (hms % 3600) % 60;
- /* Number of years in days */ /*算出当前年份,起始的计数年份为1970年*/
- for (i = STARTOFTIME; day >= days_in_year(i); i++) {
- day -= days_in_year(i);
- }
- tm->tm_year = i;
- /* Number of months in days left */ /*计算当前的月份*/
- // if (leapyear(tm->tm_year)) {
- // days_in_month(FEBRUARY) = 29;
- // }
- for(i = 1; day >= MonthDay[leapyear(tm->tm_year)][i-1]; i++)
- {
- day -= MonthDay[leapyear(tm->tm_year)][i-1];
- }
- // days_in_month(FEBRUARY) = 28;
- tm->tm_mon = i;
- /* Days are what is left over (+1) from all that. *//*计算当前日期*/
- tm->tm_day = day + 1;
- /* Determine the day of week*/
- GregorianDay(tm);
- }
- /*===================================================================
- 名 称:Is_Leap_Year
- 功 能:
- 入口参数:uint16 year
- 出口参数:uint8 TRUE or FALSE
- 作 者:
- WebSite:www.elecbench.com
- 创建日期:2011-3-30 17:14:05
- 修改日期:
- 说 明:
- ===================================================================*/
- BOOL Is_Leap_Year(u16 nyear)
- {
- if ((nyear % 4 == 0 && nyear % 100 != 0 )|| (nyear % 400 == 0))
- return TRUE;
- return FALSE;
- }
- /*===================================================================
- 名 称:Caculate_Weekday
- 功 能:根据年月日获得星期
- 入口参数:系统日期结构体变量地址 &_system_date
- 出口参数:
- 作 者:
- WebSite:www.elecbench.com
- 创建日期:2011-3-30 17:14:01
- 修改日期:
- 说 明:
- ===================================================================*/
- // void Caculate_Weekday(DATE *p_date)
- // {
- // uint16 y;
- // uint8 m,d,c;
- // uint16 w;
- // y = p_date->year;
- // m = p_date->month;
- // d = p_date->day;
- // if(m==1) {m=13;y -= 1;}
- // if(m==2) {m=14;y -= 1;}
- // c = y / 100;
- // y %= 100;
- //
- // w = (y + y/4 + c/4 -2*c + (26*(m+1)/10) + d - 1)%7;
- // p_date->_weekday = (WEEKDAY)w;
- // }
- /*===================================================================
- 名 称:Time_Add_Secd
- 功 能:系统日期时间刷新
- 入口参数:日期变量和时间变量地址
- 出口参数:
- 作 者:
- WebSite:www.elecbench.com
- 创建日期:2011-3-30 17:13:55
- 修改日期:
- 说 明:
- ===================================================================*/
- void ap_time_add_sec(_strTime* pTime)
- {
- if (++(*pTime).tm_sec > 59)
- {
- (*pTime).tm_sec = 0; //此时(*p_time).secd已经等于60,可能导致显示60,可以考虑在这里关中断
- RefreshTime标志寄存器 = TRUE; //置刷新待机界面标志
- if (++(*pTime).tm_min > 59)
- {
- (*pTime).tm_min = 0;
- if (++(*pTime).tm_hour > 23)
- {
- (*pTime).tm_hour = 0;
- if (++pTime->tm_day > MonthDay[leapyear(pTime->tm_year)][pTime->tm_mon-1])
- {
- pTime->tm_day = 1;
- if (++pTime->tm_mon > 12)
- {
- pTime->tm_mon = 1;
- pTime->tm_year++;
- }
- }
- // if (++pTime->_weekday > sat)
- // {
- // pTime->_weekday = sun;
- // }
- }
- }
- }
- }
tiem.h文件:
- #include "config.h"
- #include "include.h"
- typedef struct
- {
- u16 tm_year; //年
- u8 tm_mon; //月
- u8 tm_day; //日
- u8 tm_hour; //小时
- u8 tm_min; //分钟
- u8 tm_sec; //秒
- u8 tm_wday; //星期
- }_strTime;
-
- u32 ap_time_date2sec(_strTime *tm);
- void ap_time_sec2date(u32 tim, _strTime * tm);
- void ap_time_add_sec(_strTime* pTime);