其他分享
首页 > 其他分享> > 如何在C中分解Unix时间

如何在C中分解Unix时间

作者:互联网

似乎没有人需要做的事情,但是我正在为嵌入式系统(OpenWRT)开发一个内核模块,其中似乎time.h确实包括timespec和time_t类型以及clock_gettime和gmtime函数,但不包括localtime,ctime,time或严格来说tm类型.

当我尝试将返回指针从gmtime强制转换为自己的结构时,我遇到了段错误.

因此,我想我会很满意地通过两种方式解决该问题-最好弄清楚如何访问该丢失的类型,或者选择如何使用我自己的方法来分解unix时间戳.

解决方法:

这应该是准确的(填写对struct tm的简化模拟,我这一年使用的是Common Era而不是1900 CE时代):

struct xtm
{
    unsigned int year, mon, day, hour, min, sec;
};

#define YEAR_TO_DAYS(y) ((y)*365 + (y)/4 - (y)/100 + (y)/400)

void untime(unsigned long unixtime, struct xtm *tm)
{
    /* First take out the hour/minutes/seconds - this part is easy. */

    tm->sec = unixtime % 60;
    unixtime /= 60;

    tm->min = unixtime % 60;
    unixtime /= 60;

    tm->hour = unixtime % 24;
    unixtime /= 24;

    /* unixtime is now days since 01/01/1970 UTC
     * Rebaseline to the Common Era */

    unixtime += 719499;

    /* Roll forward looking for the year.  This could be done more efficiently
     * but this will do.  We have to start at 1969 because the year we calculate here
     * runs from March - so January and February 1970 will come out as 1969 here.
     */
    for (tm->year = 1969; unixtime > YEAR_TO_DAYS(tm->year + 1) + 30; tm->year++)
        ;

    /* OK we have our "year", so subtract off the days accounted for by full years. */
    unixtime -= YEAR_TO_DAYS(tm->year);

    /* unixtime is now number of days we are into the year (remembering that March 1
     * is the first day of the "year" still). */

    /* Roll forward looking for the month.  1 = March through to 12 = February. */
    for (tm->mon = 1; tm->mon < 12 && unixtime > 367*(tm->mon+1)/12; tm->mon++)
        ;

    /* Subtract off the days accounted for by full months */
    unixtime -= 367*tm->mon/12;

    /* unixtime is now number of days we are into the month */

    /* Adjust the month/year so that 1 = January, and years start where we
     * usually expect them to. */
    tm->mon += 2;
    if (tm->mon > 12)
    {
        tm->mon -= 12;
        tm->year++;
    }

    tm->day = unixtime;
}

我对所有不可思议的数字表示歉意. 367 * month / 12是一个巧妙的技巧,可以生成日历的30/31天序列.该计算使用从3月开始直到修正结束的年份,这使事情变得容易,因为then日落在“年份”的末尾.

标签:unix-timestamp,time-h,c-3,linux
来源: https://codeday.me/bug/20191024/1920441.html