秒数与日期之间的相互转换

转自 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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值