While sorting out some issues for tzdist, I noticed a bug in zdump, which is still present in 2014g. Running zdump on Asia/Singapore for both 1981 and 1982 together produces the expected transition from UTC+7:30 to UTC+8 at the boundary between those years: $ ./zdump.exe -vc 1981,1983 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore Thu Dec 31 16:29:59 1981 UT = Thu Dec 31 23:59:59 1981 SGT isdst=0 Asia/Singapore Thu Dec 31 16:30:00 1981 UT = Fri Jan 1 00:30:00 1982 SGT isdst=0 Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL However, running it on 1981 and 1982 individually does not: $ ./zdump.exe -vc 1981,1982 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL $ ./zdump.exe -vc 1982,1983 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL Initially, I thought this might have to do with the fact that the transition is specified as a Zone continuation line rather than as a Rule, since zdump properly handled my extended edge-case examples to Jon Skeet a while back: http://mm.icann.org/pipermail/tz/2014-July/021162.html <http://mm.icann.org/pipermail/tz/2014-July/021162.html> zdump also properly handles Asia/Dhaka's DST transition at the end of 2009, but fails in some other similar cases. So it looks like it's more to do with the transition taking place too close to the year boundary. Part of the problem may be the transition happening in different years, UTC and local, but that doesn't seem to be all that's going on. Attached are some test cases to run against various versions of Singapore with 1981,1982 and 1982,1983; and various versions of Dhaka with 2009,2010 and 2010,2011. All of these should work, but most currently don't. (The ones that do are marked.) -- Tim Parenti
Thanks; this seems to work for my tests, but I think there may be an off-by-one from expected behavior: It includes transition times taking effect at 01-01 00:00:00Z in the previous year, presumably because the immediately prior second, included in the output, is 12-31 23:59:59Z. -- Tim Parenti On 6 September 2014 19:37, Paul Eggert <eggert@cs.ucla.edu> wrote:
Thanks for reporting that. A proposed patch is attached.
Tim Parenti wrote:
I think there may be an off-by-one from expected behavior: It includes transition times taking effect at 01-01 00:00:00Z in the previous year, presumably because the immediately prior second, included in the output, is 12-31 23:59:59Z.
Sorry, I didn't quite follow that. The intent is that if there's a transition between 12-31 23:59:59.999... UTC in year N and 01-01 00:00 UTC in year N+1, the transition is reported in year N. The other way would work too, as long as it was done consistently, but this way should be a bit easier to compute.
Although that seems reasonable, I think given the new wording in the documentation, most users would expect to find such a transition in the year you call N+1, since that's when the actual onset of the transition occurs. -- Tim Parenti sent from my Android phone On 6 Sep 2014 21:52, "Paul Eggert" <eggert@cs.ucla.edu> wrote:
Tim Parenti wrote:
I think there may be an off-by-one from expected behavior: It includes transition times taking effect at 01-01 00:00:00Z in the previous year, presumably because the immediately prior second, included in the output, is 12-31 23:59:59Z.
Sorry, I didn't quite follow that. The intent is that if there's a transition between 12-31 23:59:59.999... UTC in year N and 01-01 00:00 UTC in year N+1, the transition is reported in year N. The other way would work too, as long as it was done consistently, but this way should be a bit easier to compute.
Tim Parenti wrote:
most users would expect to find such a transition in the year you call N+1, since that's when the actual onset of the transition occurs.
I'm not so sure. In everyday English there's not a general agreement whether midnight falls at the end of day N, or between day N and day N+1, or at the start of day N+1. This ambiguity is why so many laws take effect one minute after midnight. See, for example: www.nist.gov/pml/div688/times.cfm#midnight It's plausible for zdump to consider a transition from 23:59:59 (which is inarguably the previous day) to midnight (which is ambiguous) to be in the previous day. It's also plausible for zdump to consider it to be in the next day. Whatever. It doesn't really matter, so long as zdump is consistent about it.
On 6 September 2014 23:50, Paul Eggert <eggert@cs.ucla.edu> wrote:
In everyday English there's not a general agreement whether midnight falls at the end of day N, or between day N and day N+1, or at the start of day N+1. This ambiguity is why so many laws take effect one minute after midnight.
Yes, everyday English is ambiguous here, but I would think part of the motivation for using universal time, as clarified here <https://github.com/eggert/tz/commit/fef27b6086b22784e44281bfb3ec712cf258af65>, is that it's somewhat less ambiguous as to what is meant in this regard. It's plausible for zdump to consider a transition from 23:59:59 (which is
inarguably the previous day) to midnight (which is ambiguous) to be in the previous day. It's also plausible for zdump to consider it to be in the next day. Whatever. It doesn't really matter, so long as zdump is consistent about it.
It does seem easier to calculate things the way you've done. Certainly leap seconds at 23:59:60Z would complicate this. If there's some elegant way of saying something along the lines of "inclusive of the start year except exclusive of its first instant, and exclusive of the end year except inclusive of its first instant", which is what we currently have, then we should at least include that in the docs. -- Tim Parenti
Unfortunately, it seems your example doesn't match observed behavior. Consider: Zone Test/Transition1970 2:00 - XST 1970 Jan 1 0:00u 3:00 - YST https://github.com/eggert/tz/commit/8973320770f676c249229c5c4ca402057e7ec098 says "a *loyear* of 1970 includes a transition occurring at the very start of 1970 but a *hiyear* of 1970 excludes the transition." The opposite behavior is observed: $ ./zdump.exe -Vc 1969,1970 Test/Transition1970 Test/Transition1970 Wed Dec 31 23:59:59 1969 UT = Thu Jan 1 01:59:59 1970 YST isdst=0 Test/Transition1970 Thu Jan 1 00:00:00 1970 UT = Thu Jan 1 03:00:00 1970 YST isdst=0 $ ./zdump.exe -Vc 1970,1971 Test/Transition1970 If the transition is one second later, the behavior matches the description. Currently zdump is inclusive then exclusive at a year-level, but exclusive then inclusive at a second-level. This is why I described the current behavior as "inclusive of the start year except exclusive of its first instant, and exclusive of the end year except inclusive of its first instant". Since this wording is quite awkward, it may be simpler to adjust the code to match the description you provided. I also just noticed, above, that zdump returns "YST" for both timepoints in the transition above, when this should be a transition from XST to YST. It seems that's another (related?) issue. -- Tim Parenti On 8 September 2014 15:28, Paul Eggert <eggert@cs.ucla.edu> wrote:
On 09/08/2014 11:55 AM, Tim Parenti wrote:
we should at least include that in the docs
Thanks, good point, and attached is a proposed patch to do that.
Tim Parenti wrote:
Unfortunately, it seems your example doesn't match observed behavior.
Right you are. Thanks for catching that. Since it doesn't really matter I'd rather leave the code alone, and fix the documentation to describe it, as that'd be less disruptive (and also easier to implement :-). Problem fixed in the first proposed patch attached.
I also just noticed, above, that zdump returns "YST" for both timepoints in the transition above, when this should be a transition from XST to YST.
Thanks again. That's a regression from 2014g. It occurs only on platforms that lack tm_zone in struct tm, which is why I didn't observe it. Please see proposed patches 2 and 3, attached. This suggests that we need a new code release soon. I found some minor cleanups while looking into the above, and attach them as proposed patch 4.
Sorry to be a pain, but your proposed fix at https://github.com/eggert/tz/commit/2e78bf08dce685478da73888d90fe2fb2fbfc6cd still doesn't quite read right to me. I think it's important, at least for -c, to clarify exactly what is meant by "inclusive" and "exclusive". Proposed further patch attached. Tim Parenti On 11 Sep 2014 03:17, Paul Eggert wrote:
Tim Parenti wrote:
Unfortunately, it seems your example doesn't match observed behavior.
Right you are. Thanks for catching that. Since it doesn't really matter I'd rather leave the code alone, and fix the documentation to describe it, as that'd be less disruptive (and also easier to implement :-). Problem fixed in the first proposed patch attached.
Tim Parenti wrote:
I think it's important, at least for -c, to clarify exactly what is meant by "inclusive" and "exclusive". Proposed further patch attached.
That patch is wordy and the wordiness gets in the way of clarity. I think its basic idea can be expressed more concisely by adding a few words to the example, as in the attached.
On 15 October 2014 02:57, Paul Eggert <eggert@cs.ucla.edu> wrote:
That patch is wordy and the wordiness gets in the way of clarity. I think its basic idea can be expressed more concisely by adding a few words to the example, as in the attached.
Agreed; thanks for improving this. -- Tim Parenti
On Mon, 08 Sep 2014, Tim Parenti wrote:
It does seem easier to calculate things the way you've done. Certainly leap seconds at 23:59:60Z would complicate this. If there's some elegant way of saying something along the lines of "inclusive of the start year except exclusive of its first instant, and exclusive of the end year except inclusive of its first instant", which is what we currently have, then we should at least include that in the docs.
Why not include both ends, such that a transition at the exact instant that separates year N from year N+1 would appear both at the end of the output from "zdump -c N,N+1", and at the beginning of the output from "zdump -c N+1,N+2", but would appear only once in the middle of the output from "zdump -C N,N+2". --apb (Alan Barrett)
On 9 September 2014 05:16, Alan Barrett <apb@cequrux.com> wrote:
Why not include both ends, such that a transition at the exact instant that separates year N from year N+1 would appear both at the end of the output from "zdump -c N,N+1", and at the beginning of the output from "zdump -c N+1,N+2", but would appear only once in the middle of the output from "zdump -C N,N+2".
This may be another viable solution. -- Tim Parenti
Alan Barrett wrote:
Why not include both ends
That would cause an overlap problem. The output of 'zdump -Vc 2000,2010' is the concatenation of the output of 'zdump -Vc 2000,2005' and the output of 'zdump -Vc 2005,2010'. This nice property would be spoiled if both ends were inclusive and if a transition occurred at the 2005 boundary.
The attached change (which also appears in tab-mangled form below) dealt with the problem on the system I'm using. It arranges things so that when the step-by-half-a-day time value goes over the maximum cutoff time, a final transition test is made. (This seems better than excusing the behavior based on zdump.8's language about cutoffs being "near the starts of the years.") @dashdashado 1.1 927 lines 1.2 927 lines *** /tmp/,azdump.c 2014-09-06 19:56:41.335772400 -0400 --- /tmp/,bzdump.c 2014-09-06 19:56:41.423777400 -0400 *************** *** 654,665 **** tmp = my_localtime_rz(tz, &t, &tm); if (tmp) ab = saveabbr(&abbrev, &abbrevsize, &tm); ! for ( ; ; ) { newt = (t < absolute_max_time - SECSPERDAY / 2 ? t + SECSPERDAY / 2 : absolute_max_time); if (cuthitime <= newt) ! break; newtmp = localtime_rz(tz, &newt, &newtm); if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : (delta(&newtm, &tm) != (newt - t) || --- 654,665 ---- tmp = my_localtime_rz(tz, &t, &tm); if (tmp) ab = saveabbr(&abbrev, &abbrevsize, &tm); ! while (t < cuthitime) { newt = (t < absolute_max_time - SECSPERDAY / 2 ? t + SECSPERDAY / 2 : absolute_max_time); if (cuthitime <= newt) ! newt = cuthitime; newtmp = localtime_rz(tz, &newt, &newtm); if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : (delta(&newtm, &tm) != (newt - t) || On Sat, Sep 6, 2014 at 6:54 PM, Tim Parenti <tim@timtimeonline.com> wrote:
While sorting out some issues for tzdist, I noticed a bug in zdump, which is still present in 2014g.
Running zdump on Asia/Singapore for both 1981 and 1982 together produces the expected transition from UTC+7:30 to UTC+8 at the boundary between those years:
$ ./zdump.exe -vc 1981,1983 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore Thu Dec 31 16:29:59 1981 UT = Thu Dec 31 23:59:59 1981 SGT isdst=0 Asia/Singapore Thu Dec 31 16:30:00 1981 UT = Fri Jan 1 00:30:00 1982 SGT isdst=0 Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL
However, running it on 1981 and 1982 individually does not:
$ ./zdump.exe -vc 1981,1982 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL
$ ./zdump.exe -vc 1982,1983 Asia/Singapore Asia/Singapore -9223372036854775808 = NULL Asia/Singapore -9223372036854689408 = NULL Asia/Singapore 9223372036854689407 = NULL Asia/Singapore 9223372036854775807 = NULL
Initially, I thought this might have to do with the fact that the transition is specified as a Zone continuation line rather than as a Rule, since zdump properly handled my extended edge-case examples to Jon Skeet a while back: http://mm.icann.org/pipermail/tz/2014-July/021162.html
zdump also properly handles Asia/Dhaka's DST transition at the end of 2009, but fails in some other similar cases.
So it looks like it's more to do with the transition taking place too close to the year boundary. Part of the problem may be the transition happening in different years, UTC and local, but that doesn't seem to be all that's going on.
Attached are some test cases to run against various versions of Singapore with 1981,1982 and 1982,1983; and various versions of Dhaka with 2009,2010 and 2010,2011. All of these should work, but most currently don't. (The ones that do are marked.)
-- Tim Parenti
Arthur David Olson wrote:
The attached change (which also appears in tab-mangled form below) dealt with the problem on the system I'm using.
That's almost the same as the patch I wrote independently. We must be long-lost twins. The only difference is that my patch avoids time_t overflow in some rare cases when absolute_max_time - SECSPERDAY / 2 < cuthitime.
We may save some grief down the line by specifying in zdump.8 that cutoffs are starts of UT years (as distinct from starts of local time years). We may spend some grief making cutoffs at starts of local time years.-) @dashdashado On Sat, Sep 6, 2014 at 8:24 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
Arthur David Olson wrote:
The attached change (which also appears in tab-mangled form below) dealt with the problem on the system I'm using.
That's almost the same as the patch I wrote independently. We must be long-lost twins. The only difference is that my patch avoids time_t overflow in some rare cases when absolute_max_time - SECSPERDAY / 2 < cuthitime.
participants (4)
-
Alan Barrett -
Arthur David Olson -
Paul Eggert -
Tim Parenti