Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is mktime unsetting gmtoff ? How to make mktime use the gmtoff field?

I want to get an unix timestamp from a string containing a representation of the time of the form YYYYMMDDThhmmss+TZ.

For that, I convert the string into a struct tm and then use mktime to convert it to an unix timestamp.

str = "20150228T202832+02";
struct tm time_struct = {0};
strptime(str,"%Y%m%dT%H%M%S%z", &time_struct);
uint64_t timestamp = mktime(&time_struct); /* ignore and unset TZ */

It becomes a problem when I use a different time zone than the one I'm in. The mktime function ignores and unset the tm_gmtoff field of the struct tm, returning a wrong timestamp (the difference is given by the string's time zone minus my time zone).

  • Why is mktime ignoring the tm_gmtoff field of the struct tm?
  • Why is mktime setting the tm_gmtoff field to my current time zone without modifying accordingly the rest of the struct tm ? (making the struct tm represent a different time!)

To correct this behavior, I would like to add the difference between my time zone and the time zone of the string to the fields of the struct tm, before making the call to mktime.

  • How could I get my current time zone without making a new (useless) struct tm ?
like image 402
Jav Avatar asked Oct 25 '25 13:10

Jav


1 Answers

Here is a code snippet that responds to my problem. The trick was to use the global variable timezone.

/*
    Function: timestamp_from_datetime
    Returns the timestamp corresponding to a formated string YYYYMMDDTHHMMSS+TZ

    Parameters:
        datetime - must be non-NULL

    Returns:
        The timestamp associated to datetime
 */
time_t timestamp_from_datetime(const char *datetime)
{
    struct tm time_struct = (struct tm) {0};
    strptime(datetime,"%Y%m%dT%H%M%S%z", &time_struct);
    long int gmtoff = time_struct.tm_gmtoff;
    return mktime(&time_struct) - gmtoff - timezone;
}
like image 195
Jav Avatar answered Oct 27 '25 04:10

Jav