|
发表于 2010-2-25 14:54:18
|
显示全部楼层
完整的万年历程序如下:
#define ONE_YEAR ((u32)365)
#define FOUR_YEAR ((u32)365*3 + 366)
#define ONE_DAY ((u32)60*60*24)
#define ONE_HOUR ((u32)60*60)
#define ONE_MINUTE ((u32)60)
uc16 pp1[] = {0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
uc16 pp2[] = {0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
typedef struct
{
u16 year;
u8 mon;
u8 day;
u8 hour;
u8 min;
u8 sec;
u8 week;
}RT_Time;
void GetCurrentTime(RT_Time* p, u32 seconds) // 以秒换算日期
{ // 以2000年1月1日0点为起点,周六
u32 day, tmp, tmp1;
u16 const *t;
day = seconds / ONE_DAY; // 天数
seconds = seconds % ONE_DAY;
p->hour = seconds / ONE_HOUR; // 小时
seconds = seconds % ONE_HOUR;
p->min = seconds / ONE_MINUTE; // 分
p->sec = seconds % ONE_MINUTE; // 秒
p->week = (day+6) %7;
tmp = (day / FOUR_YEAR)<<2; // 4年为一个计算周期
day = day % FOUR_YEAR; // 以4年为周期的余数
tmp1= day / ONE_YEAR; / 余数的年数
if(tmp1 == 4) // 唯一的可能:4年为周期的最后一天,12月31日
{
p->year = 2000 + tmp + 3; // 实际年份 = 2000年 + 4年期 + 4年期余数
p->mon = 12; // 12月
p->day = 31; // 31日
return;
}
else if(tmp1 == 0)
{
p->year = 2000 + tmp ; // 年份 = 2000 + 4年的周期年数
t = pp2; // 用闰年的日期来计算
}
else
{
p->year = 2000 + tmp + tmp1; // 年份 = 2000 + 4年的周期年数 + 余数的年数
day = day - (ONE_YEAR*tmp1) -1; // 第0年有366天,要多减1天
t = pp1; // 用非闰年的日期来计算
}
for(tmp =1; tmp <13; tmp++) // 月份从1开始,不超过12
{
if(day < t[tmp]) // 如果在这个月内
{
p->mon = tmp; // 置月份
p->day = day - t[tmp-1] +1; // 计算日期
return;
}
}
}
u32 SetTime(RT_Time* p) // 以日期换算成秒
{
u32 tmp,tmp1, day, year;
u16 const *t;
year= p->year - 2000;
tmp = year>>2; // 把年换算成4年周期
tmp1= year %4; // 4年周期的余数
if(tmp1 != 0) // 如果不是4年周期的第1年
{
day= tmp * FOUR_YEAR + tmp1 * ONE_YEAR +1; // 整年天数 = 4年周期数 * 4年天数 + 4年周期的余数*非闰年天数 +1(第1年为闰年,多1天)
t = pp1; // 以非闰年计数在本年内的天数
}
else // 如果是4年周期的第1年
{
day = tmp * FOUR_YEAR; // 整年天数 = 4年周期数 * 4年天数
t = pp2; // 以闰年计算在本年内的天数
}
day = day + t[p->mon-1] + p->day; // 天数 = 整年天数 +本年内天数
return (day* ONE_DAY + p->hour*ONE_HOUR + p->min*ONE_MINUTE +p->sec);
}
上述万年历计算中,与具体的器件无关的。2个函数,一个以秒换算成年、月、日、时、分、秒,另一个是以年、月、日、时、分、秒换算成秒。
以32位的秒数,可以支持136年,从2000年开始计算,可以支持到2136年。 |
|