简体   繁体   中英

C struct tm time - add hours

I have struct tm that represents time 1900-01-01 00:00:00 . How can I add offset in hours to it? For example, I have offset in hours - value 1048621 (aprox. 119.7 years).

Assuming the resulting date/time falls into the range representable by time_t , you can add the hours offset to tm::tm_hour then call mktime to normalize.

#include <time.h>
#include <stdio.h>

int main()
{
    struct tm t = { 0 };
    t.tm_mday = 1;  // Jan 1st 1900

    t.tm_hour = 1048621;
    if(mktime(&t) == -1) return 1;

    printf("%d-%02d-%02d %02d:%02d:%02d\n",
           t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
           t.tm_hour, t.tm_min, t.tm_sec);

    return 0;
}

Output :

2019-08-17 13:00:00

[ EDIT ] As pointed out in a comment, the above mktime call fails with MSVC. Turns out that Microsoft's mktime implementation does a precheck on the tm argument, and unconditionally fails if tm_year < 69 before/without even looking at the other tm fields. While it is expected for mktime to fail if the end date/time falls outside the time_t range, in particular if it is earlier than the start of the epoch (usually Jan 1st 1970), such check should normally be done after (re)normalization.

Below is updated code that adds range validation, and was verified to work with gcc and msvc .

#include <time.h>
#include <limits.h>
#include <stdio.h>

int main()
{
    const int tmYear1970 = 70;
    const int tmDay1970 = tmYear1970 * 365 + tmYear1970 / 4; //      25568
    const int tmHour1970 = tmDay1970 * 24;                   //     613632
    const int tmHourMax = INT_MAX - tmHour1970;              // 2146870015

    int tmHour = 1048621;
    if(tmHour < tmHour1970 || tmHour > tmHourMax) return 2;

    struct tm t = { 0 };
    t.tm_mday = 1; // Jan 1st 1900 12 AM

    t.tm_year = tmYear1970;
    t.tm_hour = tmHour - tmHour1970;
    t.tm_isdst = -1;
    if (mktime(&t) == -1) return 1;

    printf("%d-%02d-%02d %02d:%02d:%02d\n",
           t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
           t.tm_hour, t.tm_min, t.tm_sec);

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM