The strftime(3) '%s' format is supposed to convert a 'struct tm' into the number of seconds since the epoch (1/1/70 GMT). When it does this conversion, it uses the currently set system time zone instead of using the time zone from the 'struct tm' argument. Therefore, if the two timezones are different, incorrect results are computed. Fix: I think this should fix it. From the timegm(3) man page, "The tm_isdst and tm_gmtoff members are forced to zero by timegm()" which I guess means that the value of 'tm_gmtoff' is added into the computation before being forced to zero. How-To-Repeat: Run this program with your system time zone set to any timezone other than GMT. Notice that the value printed for "now" is different before and after the converstion. #include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> int main(int ac, char **av) { time_t now; char buf[32]; now = time(NULL); printf("now = %lu\n", (u_long)now); strftime(buf, sizeof(buf), "%s", gmtime(&now)); printf("now = %s\n", buf); return (0); }
<<On Tue, 4 Sep 2001 14:01:02 -0700 (PDT), Archie Cobbs <archie@packetdesign.com> said: > When it does this conversion, it uses the currently set > system time zone instead of using the time zone from the > 'struct tm' argument. Therefore, if the two timezones are > different, incorrect results are computed. This behavior is correct. In the general case, as codified in the ISO C standard, `struct tm' does not contain time zone information. ISO C functions such as strftime() are specified to use the system's time zone. Having said that, `%s' is not specified in either POSIX or ISO C, so we are free to make it mean anything we want. -GAWollman
Garrett Wollman wrote: > > When it does this conversion, it uses the currently set > > system time zone instead of using the time zone from the > > 'struct tm' argument. Therefore, if the two timezones are > > different, incorrect results are computed. > > This behavior is correct. In the general case, as codified in the ISO > C standard, `struct tm' does not contain time zone information. ISO C > functions such as strftime() are specified to use the system's time > zone. The current behavior of '%s' is inconsistent with every other format character supported by strftime(3). For example, if you use '%z' you get the time zone offset read directly from the struct tm; the system time zone has no effect on that conversion whatsoever. Same for '%H', etc. So at best, it violates POLA and is bizarre, undocumented behavior. -Archie __________________________________________________________________________ Archie Cobbs * Packet Design * http://www.packetdesign.com
<<On Tue, 04 Sep 2001 16:42:38 -0700, Archie Cobbs <archie@packetdesign.com> said: > For example, if you use '%z' you get the time zone offset read > directly from the struct tm; the system time zone has no effect on > that conversion whatsoever. This is a bug. POSIX says that ``Local timezone information is used as though strftime( ) called tzset( ).'' POSIX does not appear to permit the implementation to require initialization of non-standard fields in `struct tm' for strftime() to work. I would interpret the specification as requiring that strftime() always use the ``system'' timezone. In order for our implementation to meet the specification, we need to call mktime() on a copy of the input structure in order to determine the timezone to generate for `%z' and `%Z'. -GAWollman
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
(17 years later) this behavior now looks like being there forever, and glibc agrees, likely we can close this?
Works for me, at least in 12.0-RELEASE