Re: mktime() failures under PCTS testing

The ftpable-from-elsie version of the time zone code suffers the same fate as related by grant@osf; on our SunOS 4.1.1 system, after making this change to the sample code:
SCCS/s.try.c: 1.1 vs. 1.2 *** 1.1/try.c Tue Mar 22 18:45:08 1994 --- 1.2/try.c Tue Mar 22 18:45:08 1994 *************** *** 34,43 **** --- 34,53 ---- printf("mktime test: for this test, set TZ=dst0std,J057,J059\n"); printf("current value of TZ = %s\n", getenv("TZ"));
+ #if 0 if (setenv("TZ", TZ_value, 1) != 0) { printf("resetting TZ failed\n"); exit(1); } + #else + { + char buf[512]; + + (void) strcpy(buf, "TZ="); + (void) strcat(buf, TZ_value); + putenv(buf); + } + #endif printf("new value of TZ = %s\n", getenv("TZ"));
time_str.tm_year = TM_year - 1900;
...I get these results:
mktime test: PCTS/STD/LS/mktime 8.1.58_9 Assert 5.1.3 mktime test: for this test, set TZ=dst0std,J057,J059 current value of TZ = (null) new value of TZ = std0dst,J057,J059 time_str tm struct set to: year = 91, mon = 1, mday = 26, hour = 2, min = 0, sec = 0, wday = -1, yday = -1, isdst = -1 expected value from mktime = 667530000
mktime returned -1 (-unknown-) mktime() final time_str tm struct reset to: year = 91, mon = 1, mday = 26, hour = 2, min = 0, sec = 0, wday = -1, yday = -1, isdst = -1
Vintage time zone hands will recognize this as behavior that certain SunOS versions of the "cron" program clashed with. The time zone package is assuming that the "mktime" call is asking a question such as... If US DST rules are in effect and I'm in the Eastern US, when, on April 3, 1994, will a wall clock show 2:30 a.m. (irrespective of whether it is or isn't daylight saving time)? ...and the "-1" answer is the package's way of saying... There is no such time! If someone has the relevant wording from the current version of the relevant standard(s) on what to do here, I'd love to hear from you. --ado

Date: Tue, 22 Mar 94 19:03:37 EST From: ado@elsie.nci.nih.gov (Arthur David Olson) The time zone package is assuming that the "mktime" call is asking a question such as... If US DST rules are in effect and I'm in the Eastern US, when, on April 3, 1994, will a wall clock show 2:30 a.m. (irrespective of whether it is or isn't daylight saving time)? ...and the "-1" answer is the package's way of saying... There is no such time! If someone has the relevant wording from the current version of the relevant standard(s) on what to do here, I'd love to hear from you. The relevant standard (i.e. the C standard) is obscure in this area. The closest that it comes to addressing the problem is the ANSI C Rationale, section 4.12.2.3 (ANSI X3.159-1989 page 109), which says: If this field [tm_isdst] is set to -1 on input, one truly ambiguous case involves the transition out of daylight savings time. As DST is currently legislated in the USA, the hour 0100-0159 occurs twice, first as DST and then as standard time. Hence an unlabeled 0130 on this date is problematic. An implementation may choose to take this as DST or standard time, marking its decision in the `tm_isdst' field. It may also legitimately take this as invalid input (and return (time_t)(-1)). What the Rationale _doesn't_ say is that there are other truly ambiguous cases, e.g. the transition _into_ daylight savings time. The general rule is that mktime wraps out-of-range inputs. If mktime's input is an unlabeled time like 02:30 that does not exist, it's ambiguous as to whether the implementation should wrap this out-of-range input to 01:30 or to 03:30. But by analogy with the Rationale, it seems plausible that in this case an implementation may choose 01:30 or 03:30 (setting tm_isdst accordingly), or it may also legitimately take this as invalid input and return (time_t)(-1). Now all this is complicated by the fact that the ANSI C standard has been superseded by ISO C. ISO C did not change the standard itself, but dropped the Rationale. Furthermore, there is a series of unpublished C interpretation rulings that may bear on the issue. But from the information that is public, I would say that PCTS is broken and should get fixed. Of course, if PCTS is pickier than the standard requires, we don't have to change mktime to agree with PCTS. But it might be more consistent to do so, since (according to my reading of the code) mktime does not yield -1 for the case cited in the Rationale. It's certainly a bit unnerving that on a leap-forward day, mktime treats 01:59:60 like 03:00:00 (and 01:59:61 like 03:00:01!), but it treats 01:59:62 as an error.

If someone has the relevant wording from the current version of the relevant standard(s) on what to do here, I'd love to hear from you.
The relevant standard (i.e. the C standard) is obscure in this area. The closest that it comes to addressing the problem is the ANSI C Rationale, section 4.12.2.3 (ANSI X3.159-1989 page 109), which says:
I also found the POSIX.1 standard vague, since it largely refers to the ISO/IEC 9899 C standard. I found the X/Open XPG4 standard more helpful. XPG4 (CAE Specification: System Interfaces and Headers, Issue 4), mktime(), pg. 275, says: A positive or zero value for tm_isdst causes the mktime() function to presume initially that Daylight Savings Time, respectively, is or is not in effect for the specified time. A negative value for ^^^^^^^^^^^^^^^^^^^^ tm_isdst causes the mktime() function to attempt to determine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ whether Daylight Saving Time is in effect for the specified time. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Local timezone information is set as though mktime() called tzset(). Upon successfull completion, the values of the tm_wday and tm_yday components of the structure, and the other components are set to ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ represent the specified time since the Epoch, but with their values ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ forced to the ranges indicated in the <time.h> entry; the final value of tm_mday is not set until tm_mon and tm_year are determined. RETURN VALUE The mktime() function returns the specified time since the Epoch encoded as a value of type time_t. If the time since the Epoch cannot be represented, the funtion returns the value (time_t)-1. (^^^'s added by me) Therefore, when mktime() is called with tm_isdst = -1, the caller is saying in effect "I don't know if this date/time is Standard or Daylight Saving. Tell me what it is. Adjust the date/time, if necessary." XPG4 mktime() provides an example program with tm_isdst set to -1, which example asks the question "What day of the week is July 4, 2001?", but XPG4, unfortunately, does not tell you the answer you should get.
From: eggert@twinsun.com (Paul Eggert)
Of course, if PCTS is pickier than the standard requires, we don't have to change mktime to agree with PCTS. But it might be more consistent to do so, ...
The NIST-PCTS:151-2, Version 1.4, 12/3/93, test suite, when the struct tm is set to a date/time that falls within the ambiguous transition from standard to daylight time, and tm_isdst = -1, allows the implementation to return either the "old" standard time, or the new daylight time, but rejects a return value of -1. So it would appear in this case that NIST-PCTS favors the XPG4 notion of mktime() attempting to determine the time mode, rather than mktime() rejecting the tm_isdst = -1 input. NIST-PCTS does not not care which of the two Epoch times are returned, so is less picky. mktime() is failing only those PCTS tests which test "ambiguous" transitions from standard to daylight time. mktime() passes all the tests for "ambiguous" transitions from daylight to standard time, however. Grant Sullivan
participants (3)
-
ado
-
eggert@twinsun.com
-
Grant Sullivan