转自
http://blog.chinaunix.net/space.php?uid=20564848&do=blog&id=72670
秒数转换成日期和日期转换成秒数ARM源程序(ARM含详细注解gliethttp) 通常情况下PC上用time可以获得开机秒数,用localtime可以将秒数转换成年、月、日、时、分、秒但因为没有源代码,只是以库文件的形式提供,带来许多不便,所以在ARM上使用只能自己完成相应功能的时间互换,以下是作者完成的转换函数封装(这两个函数已经经过严格测试,没有发现问题,如发现问题,请与作者联系)代码如下:
//---------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】uint32 xDate2Seconds(_xtime *time)
//【 创建人及创建时间 】gliethttp 2006-06-08 10:19
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】该函数计算从2006年1月1日0时0分0秒起到当前时间所经过的秒数
//---------------------------------------------------------------
#define xMINUTE (60 )//1分的秒数
#define xHOUR (60*xMINUTE )//1小时的秒数
#define xDAY (24*xHOUR )//1天的秒数
#define xYEAR (365*xDAY )//1年的秒数
uint32 xDate2Seconds(_xtime *time)
{static uint32 month[12]={
/*01月*/xDAY*(0),
/*02月*/xDAY*(31),
/*03月*/xDAY*(31+28),
/*04月*/xDAY*(31+28+31),
/*05月*/xDAY*(31+28+31+30),
/*06月*/xDAY*(31+28+31+30+31),
/*07月*/xDAY*(31+28+31+30+31+30),
/*08月*/xDAY*(31+28+31+30+31+30+31),
/*09月*/xDAY*(31+28+31+30+31+30+31+31),
/*10月*/xDAY*(31+28+31+30+31+30+31+31+30),
/*11月*/xDAY*(31+28+31+30+31+30+31+31+30+31),
/*12月*/xDAY*(31+28+31+30+31+30+31+31+30+31+30)
};
uint32 seconds;
uint8 year;
year = time->year-06; //不考虑2100年千年虫问题
seconds = xYEAR*year + xDAY*((year+1)/4);//前几年过去的秒数
seconds += month[time->month-1]; //加上今年本月过去的秒数
if( (time->month > 2) && (((year+2)%4)==0) )//2008年为闰年
seconds += xDAY; //闰年加1天秒数
seconds += xDAY*(time->day-1); //加上本天过去的秒数
seconds += xHOUR*time->hour; //加上本小时过去的秒数
seconds += xMINUTE*time->minute; //加上本分钟过去的秒数
seconds += time->second; //加上当前秒数
return seconds;
}
//---------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】void xSeconds2Date(uint32 seconds,_xtime *time)
//【 创建人及创建时间 】gliethttp 2006-06-08 10:20
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】秒数转换为年、月、日、时、分、秒
//---------------------------------------------------------------
void xSeconds2Date(uint32 seconds,_xtime *time)
{static uint8 month[12]={
/*01月*/31,
/*02月*/28,
/*03月*/31,
/*04月*/30,
/*05月*/31,
/*06月*/30,
/*07月*/31,
/*08月*/31,
/*09月*/30,
/*10月*/31,
/*11月*/30,
/*12月*/31
};
uint32 days;
uint16 leap_y_count;
time->second = seconds % 60;//获得秒
seconds /= 60;
time->minute = seconds % 60;//获得分
seconds /= 60;
time->hour = seconds % 24;//获得时
days = seconds / 24;//获得总天数
leap_y_count = (days + 365) / 1461;//过去了多少个闰年(4年一闰)
if( ((days + 366) % 1461) == 0)
{//闰年的最后1天
time->year = 06 + (days / 366);//获得年
time->month = 12; //调整月
time->day = 31;
return;
}
days -= leap_y_count;
time->year = 06 + (days / 365); //获得年
days %= 365; //今年的第几天
days = 01 + days; //1日开始
if( (time->year % 4) == 0 )
{
if(days > 60)--days; //闰年调整
else
{
if(days == 60)
{
time->month = 2;
time->day = 29;
return;
}
}
}
for(time->month = 0;month[time->month] < days;time->month++)
{
days -= month[time->month];
}
++time->month; //调整月
time->day = days; //获得日
}
转自Linux源码
long rtt_mktime(DATE_TIME time, long timezone /*= 8*/)
{
long res;
// 1..12 -> 11,12,1..10, Puts Feb last since it has leap day
if (time.month <= 2)
{
time.month += 10;
time.year -= 1;
}
else
{
time.month -= 2;
}
/**//*
// Calculate how much days from 1970 to today
res = 59; //31@0001-January and 28@0001-February
res += (time.year - 1) * 365; //at least 365 days one year
res += time.year / 4 - time.year / 100 + time.year / 400; //leap years from 0001
res += 367 * time.month / 12 - 30; //days from March(0.5/7<=slope<0.5/5)
res += time.day - 1; //days
res -= 719162; //days from 0001-1-1 to 1970-1-1
// Calculate how much seconds
res = ( (res * 24 + time.hour) * 60 + time.minute) * 60 + time.second;
*/
/***
res = (long)(time.year/4 - time.year/100 + time.year/400) +
367*time.month/12 + time.day +
time.year*365 - 719499;
res = ((res*24 + time.hour // now have hours
)*60 + time.minute // now have minutes
)*60 + time.second; // finally seconds
//*/
res -= timezone * 60 * 60;
return res;
}
int rtt_isleap(unsigned short year)
{
return ((year%4==0)&&(year%100!=0)||(year%400==0));
}
void rtt_localtime(long res, DATE_TIME *time, long timezone /*= 8*/)
{
const int monthLengths[2][13] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366},
};
const int yearLengths[2] = { 365, 366 };
int year;
int month;
int minMonth;
int maxMonth;
int days;
int clock;
int isLeap;
res += timezone*60*60;
days = res / 86400;
clock = res % 86400;
if(clock < 0)
{
clock += 86400;
days -= 1;
}
/**/
// Calcaulate year, 11323=0x3A4FC880/86400; 13879=0x47798280/86400
/**
if(days >= 0)
{
year = days/366;
days -= year*365 + (year+1)/4 - (year+69)/100 + (year+369)/400;
for(time->year = year + 1970; ; time->year++)
{
isLeap = rtt_isleap(time->year);
if(days < yearLengths[isLeap])
{
break;
}
days -= yearLengths[isLeap];
}
}
else
{
year = days/366;
days -= year*365 + (year-2)/4 - (year-30)/100 + (year-30)/400;
for(time->year = year + 1970 - 1; ; time->year--)
{
isLeap = false;//rtt_isleap(time->year);
days += yearLengths[isLeap];
if(days >= 0)
{
break;
}
}
}
/**///
// compute month and day, use the half search save time
/**
minMonth = 0;
maxMonth = 12;
for(month = 5; month < 12 && month > 0; month = (minMonth + maxMonth) / 2)
{
// days between monthLengths[month]<=days<monthLengths[month+1]
if(days < monthLengths[isLeap][month]) //too big
{
maxMonth = month;
}
else if(days >= monthLengths[isLeap][month + 1]) //too small
{
minMonth = month;
}
else //so it is
{
break;
}
}
days -= monthLengths[isLeap][month];
time->month = month + 1;
time->day = days + 1;
/**///
// Calcaulate hour minute and second
/**///
time->hour = clock / 3600; //3600s one hour
clock = clock % 3600;
time->minute = clock / 60; //60s one minute
time->second = clock % 60; //ms
}
/*========================================================================
* Function name : gmt_convert_local
* Description : 将格林尼治时间转换为本地时间
* Return type : bool
* Argument :
* : const char* gmt 格林尼治时间 20091105082121
* : char* local 20091105/162121
========================================================================*/
bool gmt_convert_local(const char* gmt, char* local)
{
if ( strlen(gmt) != 14 )
return false;
//格林尼治时间转换为本地时间
char year[5];
char month[3];
char day[3];
char hour[3];
char minute[3];
char second[3];
sscanf(gmt, "%4s%2s%2s%2s%2s%2s", year, month, day, hour, minute, second);
DATE_TIME utc_time;
DATE_TIME local_time;
utc_time.year = atoi(year);
utc_time.month = atoi(month);
utc_time.day = atoi(day);
utc_time.hour = atoi(hour);
utc_time.minute = atoi(minute);
utc_time.second = atoi(second);
long time_second = rtt_mktime(utc_time, 0);//utc时间, 0 时区
rtt_localtime(time_second, &local_time, 8);
sprintf(local, "%04d%02d%02d/%02d%02d%02d", local_time.year, local_time.month, local_time.day,
local_time.hour, local_time.minute, local_time.second);
return true;
}