A NOTE has been added to this issue. ====================================================================== https://austingroupbugs.net/view.php?id=1533 ====================================================================== Reported By: steffen Assigned To: ====================================================================== Project: 1003.1(2016/18)/Issue7+TC2 Issue ID: 1533 Category: Base Definitions and Headers Type: Enhancement Request Severity: Editorial Priority: normal Status: New Name: steffen Organization: User Reference: Section: time.h Page Number: 425 Line Number: 14451 Interp Status: --- Final Accepted Text: ====================================================================== Date Submitted: 2021-11-08 22:04 UTC Last Modified: 2022-03-14 00:31 UTC ====================================================================== Summary: struct tm: add tm_gmtoff (and tm_zone) field(s) ======================================================================
---------------------------------------------------------------------- (0005745) steffen (reporter) - 2022-03-14 00:31 https://austingroupbugs.net/view.php?id=1533#c5745 ---------------------------------------------------------------------- Hello. So i apologize for the long duration that it took before i was able to look into the outcome of the standard's February 3, 2022 teleconference, as Don Cragun noted in #5657: [.] we need a more fully fleshed-out proposal including details of how the storage for tm_zone may be affected by later calls (including tzset()). This is likely to be different for localtime() and localtime_r(). There will also be changes needed to the strftime() page, for example, where it lists the tm members that affect each conversion. I want to start with responding to Geoff Clare's note #5530, which i also never seem to have done before. #5530 On an implementation that lacks tm_gmtoff and tm_zone, if you change TZ after obtaining a struct tm from localtime(), the strftime() %z and %Z conversions use the values for the new TZ. Adding tm_gmtoff and tm_zone would change the behaviour such that %z and %Z use the values for the old TZ. This could break existing applications when they are recompiled and consequently start using the new ABI. The standard already seems to be prepared to handle these concerns by leaving the according behaviour undefined. On page 2047, starting with line 65628 (in 2018 Edition of Issue 7) one can read in the description for strftime(): If a struct tm broken-down time structure is created by localtime( ) or localtime_r( ), or modified by mktime( ), and the value of TZ is subsequently modified, the results of the %Z and %z strftime( ) conversion specifiers are undefined, when strftime( ) is called with such a broken-down time structure. This makes it clear that strftime() only produces valid results if the value of $TZ equals the one that was in use once localtime() or localtime_r() filled in a struct tm. "Undefined" behaviour is a very strong wording already today. In direct succession one can read for gmtime(_r)?(): If a struct tm broken-down time structure is created or modified by gmtime( ) or gmtime_r( ), it is unspecified whether the result of the %Z and %z conversion specifiers shall refer to UTC or the current local timezone, when strftime( ) is called with such a broken-down time structure. This also seems to neatlessly fit a standard extension that brings .tm_gmtoff and .tm_zone, a change of $TZ in between gmtime() and strftime() will either be honoured, or not, if the information is at all accessed. For time.h, struct tm, on page 425, append after line 14450, long tm_gmtoff Seconds east of UTC. const char *tm_zone Timezone abbreviation. And after line 14452 If the value of tm_zone is accessed after the value of TZ is modified, and the zone name was not "UTC", the behaviour is undefined. For gmtime, on page 1113, lines 37692 ff., append after Upon successful completion, gmtime_r( ) shall return the address of the structure pointed to by the argument result. the sentence The structures tm_zone member shall be set to the string "UTC", which shall have permanently valid storage scope. For localtime, on page 1265, lines 42225 ff., append after Unlike localtime( ), the localtime_r( ) function is not required to set tzname. If localtime_r( ) sets tzname, it shall also set daylight and timezone. If localtime_r( ) does not set tzname, it shall not set daylight and shall not set timezone. the sentence If the struct tm member tm_zone is accessed after the value of TZ is subsequently modified, the behaviour is undefined. For strftime, on page 2047, lines 65619 ff., change z Replaced by the offset from UTC in the ISO 8601: 2004 standard format (+hhmm or −hhmm), or by no characters if no timezone is determinable. For example, "−0430" means 4 hours 30 minutes behind UTC (west of Greenwich). If tm_isdst is zero, the standard time offset is used. If tm_isdst is greater than zero, the daylight savings time offset is used. If tm_isdst is negative, no characters are returned. [tm_isdst] to [.] [tm_isdst, tm_gmtoff] and lines 65624 ff. from Z Replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. [tm_isdst] to [.] [tm_isdst, tm_zone] For tzset, on page 2185, append after the lines 69918 ff.: The tzset( ) function shall set the external variable tzname as follows: tzname[0] = "std"; tzname[1] = "dst"; where std and dst are as described in XBD Chapter 8 (on page 173). the sentence The TZ name "UTC" shall be made available in permanently valid storage scope. Since the standard already makes clear, on the lines 69926 ff., that thread-safety cannot be expected: If a thread accesses tzname, daylight, or timezone directly while another thread is in a call to tzset( ), or to any function that is required or allowed to set timezone information as if by calling tzset( ), the behavior is undefined. The data backing the timezone information can always be accessed "atomically" from the user's point of view. Explicitly adding words for the tm_zone fields of struct tm a second time seems redundant. (It may be beneficial to add wording to the daylight, timezone, tzname in time.h, page 427, and refer to the documentation of tzset().) P.S.: On page 1266 line 42269 there is a documentation error, present in C181.pdf (i first thought it was caused by the pdftotext(1) convertion); it should be ==, 42269 if(stat(pathname, &statbuf) = = −1) 42270 return −1; I have not verified all in PDF, but searching for "= =" in the pdftotext(1) conversion gives 28 hits. (I now seem to remember having read a bug on mis-styles, but am not currently online.) Issue History Date Modified Username Field Change ====================================================================== 2021-11-08 22:04 steffen New Issue 2021-11-08 22:04 steffen Name => steffen 2021-11-08 22:04 steffen Section => time.h 2021-11-08 22:04 steffen Page Number => 425 2021-11-08 22:04 steffen Line Number => 14451 2021-11-21 22:28 steffen Note Added: 0005529 2021-11-22 09:47 geoffclare Note Added: 0005530 2021-11-22 10:12 geoffclare Note Added: 0005531 2021-11-22 10:50 geoffclare Note Added: 0005532 2021-11-22 15:26 steffen Note Added: 0005533 2021-11-22 15:36 steffen Note Added: 0005534 2022-02-03 16:58 shware_systems Note Added: 0005656 2022-02-03 17:32 Don Cragun Note Added: 0005657 2022-02-03 18:41 kre Note Added: 0005658 2022-02-03 22:18 steffen Note Added: 0005660 2022-02-06 11:37 mirabilos Note Added: 0005664 2022-02-06 23:28 kre Note Added: 0005667 2022-03-14 00:31 steffen Note Added: 0005745 ======================================================================
