On Wed, Nov 02, 2022 at 02:54:01PM +0000, Taylor R Campbell wrote: > Suppose you create a struct tm _without_ gmtime(3) or localtime(3), > using designated initializers or memset for zero-initialization, with > only what is included in POSIX: > > [...] > > This struct tm doesn't specify a time zone in which to interpret the > calendar date. So what time_t do you get out of mktime(&tm), or what > number is represented by the string you get out of strftime(..., "%s", > &tm)? > > [...] > > Now what if TZ is not UTC, say TZ=Europe/Berlin? It obviously depends > on whether mktime and strftime examine TZ or tm_gmtoff. Here are some > possible rules to answer this:
How about: 5. Also add a field tm_tzinfo to struct tm, with three possible values TZINFO_UNSET (which is 0), TZINFO_LOCAL, TZINFO_EXPLICIT. Then if you cons up your own struct tm without knowing about the zone fields, and either bzero it or give it a suitable initializer, it will come out with TZINFO_UNSET. If it comes from localtime(), it'll come from TZINFO_LOCAL. In other cases (including both gmtime() and intentional use) you set it to TZINFO_EXPLICIT. Then in mktime you use the last tzset() result for TZINFO_UNSET (which is required for compat with portable code) and for TZINFO_LOCAL (which is required for the corner case you came up with involving calling tzset again), and for TZINFO_EXPLICIT you use the zone info in the struct tm. I think that correctly covers all the cases that have been suggested so far. (This is why I mumbled yesterday about maybe needing a compat mess to fix our code; we don't have such a field, and checking the timezone name pointer for NULL isn't quite adequate. Though maybe setting it to something reserved in localtime would do the trick.) > It seems to me either we need a new API, or we risk breaking existing > programs. I don't think so. (On the subject of initializers vs. bzero and whatnot, that's a red herring.) -- David A. Holland dholl...@netbsd.org