#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;
// }
}
}
}
}