Getting utc timestamp using strftime ()

I am trying to encode the current utc time into a string using the strftime function:

 time_t now; struct tm nowLocal; struct tm nowUtc; now = time(NULL); localtime_r(&now, &nowLocal); gmtime_r(&now, &nowUtc); 

So far so good: nowLocal contains the current time in my time zone (CET), nowUtc contains the utc time, the difference exactly matches the value of tm_gmtoff :

 nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} nowUtc: {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"} 

Then I call strftime() with the format "%s" to get seconds from the era:

 char tsFromLocal[32]; char tsFromUtc[32]; strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal); strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc); 

The result seems strange to me. I expected to get exactly the same string from both strftime() calls, as the %s format is described as:

The number of seconds since an era, i.e. from 1970-01-01 00:00:00 UTC . Seconds of seconds are not counted if there is no support of the second level.

But I have two different meanings:

 tsFromLocal:"1337772448" tsFromUtc: "1337768848" 

and, in addition, the difference is not 7200 ( tm_gmtoff ), but 3600 . Can someone explain this behavior? Or is this a mistake?

The reason I do this is because I need to transfer the time value over the network and compare it with the current time on the target machine, which may be in different time zones. On the target machine, I wanted:

 struct tm restoredUtc; time_t restored; strptime(tsFromUtc, "%s", &restoredUtc); restored = timegm(&restoredUtc); 

But I got:

 restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} 

So strptime() sets tm_zone according to the current tm_zone . But even if I used timelocal() instead of timegm() , I won’t get the correct value, since it should be 11:27:28 CEST and not 12:27:28 CEST . Is this error related to different strftime() results?

Any comments on this later part?

+4
source share
3 answers

You are probably best off using GMT all over gmtime_r , which will always give you the same answer everywhere. If a separate computer wants to display at local time, this can be done later, but a good binding to one time zone for storage and transmission over the network is a good idea, and the default values ​​are easy to get.

+2
source

I suspect the comment is correct: strftime() interprets the time as local time. Note that tm_gmtoff not a standardized field; Interestingly, even if strftime() even looks at it. But I can not find anything concrete to confirm this.

However, in answering the second part of your question, why not just simply pass the time(NULL) results over the network directly? Or, if you already have time in the form of struct tm , use mktime() to convert to time_t , and then pass this? printf("%lu", (unsigned long) time) much simpler than trying to use strftime("%s") , which is not standardized by C99 or POSIX.

0
source

Q1: Can someone explain this behavior? Or is this a mistake?

Yes, this is an error in tsFromLocal:"1337772448" ! = tsFromUtc: "1337768848" . But the error is in tsFromUtc . They must be the same and both must be 1337772448.

1337772448% (24 * 60 * 60) β†’ 41248 - UTC seconds of the day or 11:27:28, which corresponds to your nowUtc structure, and this is the time you are thinking about (in UTC format)

Q2: ... Is this error related to different strftime () results?

I agree with the general idea of ​​using time_t as a whole for network communication.

Yes it is.

If you want to go further in this post: consider placing the numeric value now immediately after time(&now) and clearly indicate what time you expected it to be then.

0
source

Source: https://habr.com/ru/post/1413931/


All Articles