From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/12375 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Differences between strftime in musl and glibc Date: Thu, 18 Jan 2018 11:34:52 -0500 Message-ID: <20180118163452.GQ1627@brightrain.aerifal.cx> References: Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1516293190 20295 195.159.176.226 (18 Jan 2018 16:33:10 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 18 Jan 2018 16:33:10 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-12391-gllmg-musl=m.gmane.org@lists.openwall.com Thu Jan 18 17:33:06 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1ecD7f-0004mW-HN for gllmg-musl@m.gmane.org; Thu, 18 Jan 2018 17:33:03 +0100 Original-Received: (qmail 1624 invoked by uid 550); 18 Jan 2018 16:35:05 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 1602 invoked from network); 18 Jan 2018 16:35:04 -0000 Content-Disposition: inline In-Reply-To: Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:12375 Archived-At: On Thu, Jan 18, 2018 at 04:25:07PM +0000, Adrián López Tejedor wrote: > Hi, > > I was having a problem parsing dates with python in an Alpine container and > after some time digging I have found a difference in how musl and > glibc calculate the unix Epoch using strftime. > > The format specifier to get the unix epoch is "%s", which is an extension > of GNU ( > https://www.gnu.org/software/libc/manual/html_node/Formatting-Calendar-Time..html > ). > > In Glibc they use mktime ( > https://github.com/bminor/glibc/blob/master/time/strftime_l.c#L1127), being > this function aware of time zone. > > In musl is calculated without mktime, adding the seconds of each part of > the tm struct ( > https://git.musl-libc.org/cgit/musl/tree/src/time/strftime.c?h=v1.1.18#n132) > and substracting the GMT offset. This method is unaware of the TZ data (I > have not seen how to define that gmt offset when using strptime). > > Calling directly to musl/mktime work as expected. > > I have attached a small program which shows the difference between musl and > glibc. > > Compiled with glibc: > $ TZ=Europe/Madrid ./a.out > strftime: -3600 > mktime: -3600 > $ TZ=America/New_York ./a.out > strftime: 18000 > mktime: 18000 > > > Compiled with musl: > $ TZ=Europe/Madrid ./a.out > strftime: 0 > mktime: -3600 > $ TZ=America/New_York ./a.out > strftime: 0 > mktime: 18000 > > > Thanks! > Adrián > #define _XOPEN_SOURCE > #include "stdio.h" > #include "stdlib.h" > #include "time.h" > #include "string.h" > > > int main(void) { > char buf[100]; > struct tm tm1, tm2; > memset(&tm1, 0, sizeof(struct tm)); > memset(&tm2, 0, sizeof(struct tm)); > strptime("1/1/1970 00:00:00", "%d/%m/%Y %H:%M:%S", &tm1); > strptime("1/1/1970 00:00:00", "%d/%m/%Y %H:%M:%S", &tm2); > > strftime(buf, 100, "%s", &tm1); > printf("strftime: %s\n", buf); > > time_t seg = mktime(&tm2); > printf("mktime: %ld\n", seg); > > return 0; > } The glibc behavior assumes the tm object is in units of local time (in the current time zone), which is a really bad assumption, since everything else about the strftime API is timezone-agnostic and works with tm objects produced by gmtime() as well as local times. So I believe the musl behavior is correct and the glibc behavior is wrong, but I'm open to further discussion. It probably needs to happen on the Austin Group tracker/list, as %s is scheduled for inclusion in future versions of POSIX but grossly underspecified: http://austingroupbugs.net/view.php?id=169 In particular, the glibc behavior requires that strftime become aware of [changes in] the timezone, which it's currently not specified to do, and there's no specification of if or how strftime determines if the argument is a local or UTC time. My preference would be to say that, unless the struct tm was produced by localtime[_r] or derived from such a struct tm, it's unspecified what time zone %s is referenced against. But I'm open to discussion as part of the standardization process. Rich