如题,发一个RTC和时间互转工具 U =unsigned UC=unsigned const
由某个操作系统源代码修改而来。经初步测试没有错误,大家帮我再测试测试。
#define OFFSET_SECOND 946684800 /* 从1970/1/1/0/0/0到2000/1/1/0/0/0之间的总秒数 */
//#define OFFSET_SECOND 0 /* 从2000/1/1/0/0/0到2000/1/1/0/0/0之间的总秒数 */
#define SECOND_OF_DAY 86400 /* 1天的秒数 */
typedef struct st_date_time
{
U16 Year; //年1970-2108
U8 Mon; //月1-12
U8 Day; //日1-31
U8 Hour; //时0-23
U8 Min; //分0-59
U8 Sec; //秒0-59
U8 WDay; //星期0-6 周日=0 周六=6
} DATE_TIME;
//1970年起的138年秒和日期互转,没有2038年问题
//计算效率 <0.1ms STM32F100/24M
static UC8 DayOfMon[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
// 返回由1970/1/1/0/0/0起的秒
U32 TimeSec(DATE_TIME *time)
{
U32 iYear, iMon, iDay, iHour, iMin, iSec;
U32 i, Cyear=0;
U32 CountDay=0;
iYear = time->Year;
iMon = time->Mon;
iDay = time->Day;
iHour = time->Hour;
iMin = time->Min;
iSec = time->Sec;
for(i=1970; i<iYear; i++) /* 统计1970年到本年之前的闰年数 */
{
if(((i%4==0) && (i%100!=0)) || (i%400==0)) Cyear++;
}
CountDay = Cyear * 366 + (iYear-1970-Cyear) * 365;
for(i=1; i<iMon; i++)
{
if((i==2) && (((iYear%4==0)&&(iYear%100!=0)) || (iYear%400==0)))
CountDay += 29;
else
CountDay += DayOfMon[i-1];
}
CountDay += (iDay-1);
CountDay = CountDay*SECOND_OF_DAY + (unsigned long)iHour*3600 + (unsigned long)iMin*60 + iSec;
return CountDay;
}
// 由秒时计算基于1970/1/1/0/0的日期
void SecTime(U32 sec, DATE_TIME *time)
{
U32 i,j,iDay;
U32 lDay;
lDay = sec / SECOND_OF_DAY; /* 转为基于天的时间 */
sec = sec % SECOND_OF_DAY;
time->WDay=(lDay+4)%7;
i = 1970;
while(lDay > 365)
{
if(((i%4==0)&&(i%100!=0)) || (i%400==0)) /* 闰年 */
lDay -= 366;
else
lDay -= 365;
i++;
}
if((lDay == 365) && !(((i%4==0)&&(i%100!=0)) || (i%400==0))) /* 平年 */
{
lDay -= 365;
i++;
}
time->Year = i; /* 得到年份 */
for(j=0;j<12;j++) /* 计算月份 */
{
if((j==1) && (((i%4==0)&&(i%100!=0)) || (i%400==0)))
iDay = 29;
else
iDay = DayOfMon[j];
if(lDay >= iDay) lDay -= iDay;
else break;
}
time->Mon = j+1;
time->Day = lDay+1;
time->Hour = sec / 3600;
time->Min = (sec % 3600) / 60;
time->Sec = (sec % 3600) % 60;
}
|