Search code examples
c++datetimec++11timemktime

Why is mktime returning -1 for my std::tm


I have a std::tm that looks correct.

enter image description here

However when normalizing with mktime I am seeing a -1

According to man mktime:

The mktime() function returns the specified calendar time; if the calendar time cannot be represented, it returns -1;

However, looking at the screenshot I posted, I dont see what is wrong with what is being put in the std::tm Is there a problem with tm_gmtoff and tm_zone?


Solution

  • The tm_year member of a struct tm object denotes years since 1900, not the year number. Setting tm_year to 2014 refers to the year 3914, which is likely outside the range of time_t. On many systems, a time_t value is a signed 32-bit integer representing seconds since 1970-01-01 00:00:00 UTC, which overflows in the year 2038.

    The reasons for this are historical. When this interface was invented, years were stored using 2 digits, because that seemed to be the reasonable thing to do at the time. It was later updated to be able to refer to years after 1999 consistently, but it wasn't possible to change existing values without breaking existing code.

    Something else to watch out for: the tm_mon member encodes January as 0 and December as 11; this is convenient for use as an index into an array of month names. The tm_mon value of 5 in your example refers to June, not May.

    The tm_gmtoff and tm_zone members are non-standard; they're specific to your implementation. Implementations are permitted to add additional members to struct tm, but you should be aware only first 9 members in your list are standard; code that depends on any of the others will not be portable.