系统时间与时区

经过几次吐血的教训,不要去转换时区。

用世界时间,100年不动摇。

时间转换(localtime和mktime),有些系统没有localtime和mketime, 把linux内核里边这两函数扣出来用。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdint.h>

struct tm {
    /*
     * the number of seconds after the minute, normally in the range
     * 0 to 59, but can be up to 60 to allow for leap seconds
     */
    int tm_sec;
    /* the number of minutes after the hour, in the range 0 to 59*/
    int tm_min;
    /* the number of hours past midnight, in the range 0 to 23 */
    int tm_hour;
    /* the day of the month, in the range 1 to 31 */
    int tm_mday;
    /* the number of months since January, in the range 0 to 11 */
    int tm_mon;
    /* the number of years since 1900 */
    long tm_year;
    /* the number of days since Sunday, in the range 0 to 6 */
    int tm_wday;
    /* the number of days since January 1, in the range 0 to 365 */
    int tm_yday;

    int tm_isdst;
};

static unsigned long mktime(const unsigned int year0, const unsigned int mon0,
        const unsigned int day, const unsigned int hour,
        const unsigned int min, const unsigned int sec)
{
    unsigned int mon = mon0, year = year0;

    /* 1..12 -> 11,12,1..10 */
    if (0 >= (int) (mon -= 2)) {
        mon += 12;    /* Puts Feb last since it has leap day */
        year -= 1;
    }

    return ((((unsigned long)
          (year/4 - year/100 + year/400 + 367*mon/12 + day) +
          year*365 - 719499
        )*24 + hour /* now have hours */
      )*60 + min /* now have minutes */
    )*60 + sec; /* finally seconds */
}


static struct tm * localtime_r(time_t *srctime,struct tm *tm_time)
{
    long int n32_Pass4year,n32_hpery;
    const static char Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const static int ONE_YEAR_HOURS = 8760;

    time_t time = *srctime;
    time=time+28800;
    tm_time->tm_isdst=0;
    if(time < 0)
    {
    time = 0;
    }

    tm_time->tm_sec=(int)(time % 60);
    time /= 60;
    tm_time->tm_min=(int)(time % 60);
    time /= 60;
    tm_time->tm_wday=(time/24+4)%7;
    n32_Pass4year=((unsigned int)time / (1461L * 24L));
    tm_time->tm_year=(n32_Pass4year << 2)+70;
    time %= 1461L * 24L;
    tm_time->tm_yday=(time/24)%365;

    for (;;)
    {
        n32_hpery = ONE_YEAR_HOURS;
        if ((tm_time->tm_year & 3) == 0)
        {
            n32_hpery += 24;
        }

        if (time < n32_hpery)
        {
            break;
        }

        tm_time->tm_year++;
        time -= n32_hpery;
    }

    tm_time->tm_hour=(int)(time % 24);
    time /= 24;
    time++;

    if ((tm_time->tm_year & 3) == 0)
    {
        if (time > 60)
        {
            time--;
        }
        else
        {
            if (time == 60)
            {
                tm_time->tm_mon = 1;
                tm_time->tm_mday = 29;
                return tm_time;
            }
        }
    }

    for (tm_time->tm_mon = 0;Days[tm_time->tm_mon] < time;tm_time->tm_mon++)
    {
        time -= Days[tm_time->tm_mon];
    }

    tm_time->tm_mday = (int)(time);
    return tm_time;
}

int main(void)
{
    uint32_t now = 1451577600; /*2016/01/01 00:00:00*/
    struct tm tm = {0};
    char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    localtime_r(&now, &tm);
    printf("%d/%d/%d \n", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
    printf("%s %d:%d:%d \n", wday[tm.tm_wday], tm.tm_hour, tm.tm_min, tm.tm_sec);
    now = mktime(1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
    printf("rtc value : %d\n", now);
    return 0;
}

 

posted @ 2017-11-06 01:04  dong1  阅读(519)  评论(0编辑  收藏  举报