[tz] NetBSD and Android bionic APIs for tz values

Paul Eggert eggert at cs.ucla.edu
Tue Aug 19 00:19:59 UTC 2014

Guy Harris wrote:
> Not all OSes can do that, however, as not all OSes with "struct tm" have "tm_zone" and "tm_gmtoff" members of that structure.

Yes, that's right, the proposal is tuned for platforms that have time 
zone info in struct tm.  Unfortunately if a struct tm is bare-bones and 
lacks this info, NetBSD's strftime_z can misbehave on time zones that 
don't fall into the simple POSIX model, because it cannot deduce 
strictly from a bare-bones struct tm what the time zone or abbreviation 
was for a past time stamp.  For example, suppose TZ='Africa/Tripoli' and 
a bare-bones struct tm says only 2012-11-10 01:30:00 with tm_isdst == 0. 
  This is ambiguous: it could be EET and it could be CET, as Libya 
changed time zones at 02:00 and repeated that hour without observing DST 
either before or after the transition.  In this example, NetBSD's 
strftime_z guesses when formatting %Z or %z, and sometimes guesses 
wrongly.  But the proposed tm_strftime function won't guess and will do 
the right thing on NetBSD.

(In writing the above paragraph I saw a minor infelicity in the proposed 
patch -- not really a bug per se, just inelegance -- and the first 
attached patch should fix that.)

If and when tm_strftime support is added to barebones struct tm 
platforms, I suggest adding tm_gmtoff and tm_zone members to struct tm 
in the usual way that system data structures are extended.  These 
members might be hidden (e.g., they might be called __tm_gmtoff or 
whatever).  On platforms where it's too much trouble to extend struct 
tm, I suppose the tm_strftime function should simply be an alias for 
strftime, though it will continue to botch %Z and %z occasionally.

The proposed patch also fixes a C11 compatibility bug in tzcode up 
through 2014f, where strftime (when compiled with -DTM_ZONE) may access 
a bad pointer when interpreting %Z or (when compiled with -DTM_GMTOFF) 
an uninitialized integer when interpreting %z, even though the C 
standard says the behavior must not be undefined.  I forgot to document 
that fix in NEWS; second proposed patch attached.
-------------- next part --------------
From 6b0812131958c89344a3f78d0611b3040de4b6cd Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Mon, 18 Aug 2014 12:42:53 -0700
Subject: [PROPOSED PATCH 1/2] * strftime.c (_fmt): When called from
 tm_strftime, use tm_gmtoff for %z

even if tm_isdst is negative.
 strftime.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/strftime.c b/strftime.c
index ccb3c22..301e942 100644
--- a/strftime.c
+++ b/strftime.c
@@ -512,8 +512,6 @@ label:
 				long		diff;
 				char const *	sign;
-				if (t->tm_isdst < 0)
-					continue;
 #ifdef TM_GMTOFF
 				if (z)
 				  diff = t->TM_GMTOFF;
@@ -539,6 +537,8 @@ label:
 				** determinable, so output nothing if the
 				** appropriate variables are not available.
+				if (t->tm_isdst < 0)
+					continue;
 				if (t->tm_isdst == 0)
 #ifdef USG_COMPAT
 					diff = -timezone;
-------------- next part --------------
From 55fcefc06002c64aa7c52885af3251cced51dfe5 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Mon, 18 Aug 2014 14:04:04 -0700
Subject: [PROPOSED PATCH 2/2] * NEWS: Document tm_strftime better.

 NEWS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/NEWS b/NEWS
index e5c6e96..05de29c 100644
--- a/NEWS
+++ b/NEWS
@@ -47,6 +47,13 @@ Unreleased, experimental changes
     in a different time zone.  The new functions are tzalloc, tzfree,
     localtime_rz, mktime_z, posix2time_z, time2posix_z, and tm_strftime.
+    As required by the C standard, when processing %Z or %z directives
+    strftime no longer examines any struct tm time zone members such as
+    tm_zone or tm_gmtoff.  Instead, strftime attempts (sometimes
+    incorrectly) to infer time zone information from global state.
+    The new tm_strftime function generates correct output for %Z and %z
+    on struct tm objects initialized by localtime and related functions.
     tzselect -c now uses a hybrid distance measure that works better
     in Africa.  (Thanks to Alan Barrett for noting the problem.)

More information about the tz mailing list