Precise meaning of FROM and TO in a rule
Sorry to be pedantic again, but I'm trying to get my head round some fiddly code, and I've come across an interesting bit of ambiguity. FROM and TO are described <http://www.ietf.org/timezones/code/zic.8.txt> like this: FROM Gives the first year in which the rule applies. Any integer
year can be supplied; the Gregorian calendar is assumed. The word minimum (or an abbreviation) means the minimum year representable as an integer. The word maximum (or an abbreviation) means the maximum year representable as an integer. Rules can describe times that are not representable as time values, with the unrepresentable times ignored; this allows rules to be portable among hosts with differing time value types.
TO Gives the final year in which the rule applies. In addition to
minimum and maximum (as above), the word only (or an abbreviation) may be used to repeat the value of the FROM field.
It's not clear whether that "year" is: 1. The year in UTC at the transition 2. The year in the local time before the transition 3. The year in the local time after the transition 4. The year in the same frame of reference as the "AT" part Option 1 seems unlikely. Options 2 and 3 seem likely to be equivalent in all realistic time zones - it would be odd for a time zone to add an hour of DST at 11.30pm on December 31st, for example... and even odder for it to *subtract* an hour of DST at 00.30am on January 1st. Option 4 is tricky. In some ways it feels natural - if you're going to use one frame of reference for a time, why not do it for the date as well? On the other hand, it means that a "TO" value of (say) 2001 where the transition is at 2am UTC on January 1st in a time zone with a standard time of UTC+8 would actually have its last transition in 2000 local time, assuming I've got my maths right. Can I assume that one of option 2 or option 3 is intended, and that no sensible time zone will ever make those two options behave differently? I've tried reading the C source code, but given the subtleties involved, I'd rather trust a natural language description. If we can come to a conclusion about this, I'd like to propose that we amend the text to be unambiguous, too. Jon
I think this ambiguity is hard to create in practice. Transition rules are always expressed in the UTC offset that the time zone is leaving. So, even if you had this: # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER Rule Erewhon 2014 only - Jan 1 0:00 1:00 D ...that would indicate that the new zone offset begins at midnight January 1st local wall-clock time, regardless of what that wall clock time is. Say that Erewhon is UTC-6 on December 31st. The rule above unambiguously says to do this: UTC Wall clock 2013-12-31 23:59 2013-12-31 17:59 2014-01-01 00:00 2013-12-31 18:00 2014-01-01 05:59 2013-12-31 23:59 2014-01-01 06:00 2014-01-01 01:00 2014-01-01 06:01 2014-01-01 01:01 Does the C code have a different implementation? David Braverman Inner Drive Technology http://www.inner-drive.com/demo/timezones.aspx From: tz-bounces@iana.org [mailto:tz-bounces@iana.org] On Behalf Of Jon Skeet Sent: Monday 7 July 2014 15:38 To: tz@iana.org Mailing List Subject: [tz] Precise meaning of FROM and TO in a rule Sorry to be pedantic again, but I'm trying to get my head round some fiddly code, and I've come across an interesting bit of ambiguity. FROM and TO are described like this: FROM Gives the first year in which the rule applies. Any integer year can be supplied; the Gregorian calendar is assumed. The word minimum (or an abbreviation) means the minimum year representable as an integer. The word maximum (or an abbreviation) means the maximum year representable as an integer. Rules can describe times that are not representable as time values, with the unrepresentable times ignored; this allows rules to be portable among hosts with differing time value types. TO Gives the final year in which the rule applies. In addition to minimum and maximum (as above), the word only (or an abbreviation) may be used to repeat the value of the FROM field. It's not clear whether that "year" is: 1. The year in UTC at the transition 2. The year in the local time before the transition 3. The year in the local time after the transition 4. The year in the same frame of reference as the "AT" part Option 1 seems unlikely. Options 2 and 3 seem likely to be equivalent in all realistic time zones - it would be odd for a time zone to add an hour of DST at 11.30pm on December 31st, for example... and even odder for it to subtract an hour of DST at 00.30am on January 1st. Option 4 is tricky. In some ways it feels natural - if you're going to use one frame of reference for a time, why not do it for the date as well? On the other hand, it means that a "TO" value of (say) 2001 where the transition is at 2am UTC on January 1st in a time zone with a standard time of UTC+8 would actually have its last transition in 2000 local time, assuming I've got my maths right. Can I assume that one of option 2 or option 3 is intended, and that no sensible time zone will ever make those two options behave differently? I've tried reading the C source code, but given the subtleties involved, I'd rather trust a natural language description. If we can come to a conclusion about this, I'd like to propose that we amend the text to be unambiguous, too. Jon
Transitions are given in terms of the local time before the transition, as otherwise a transition could be self-referential. A single rule can specify multiple transitions, and it's reinterpreted each time it's used. Perhaps the following change to zic.8? diff --git a/zic.8 b/zic.8 index fb8f882..bd9dfeb 100644 --- a/zic.8 +++ b/zic.8 @@ -283,6 +283,7 @@ or if the given time is universal time; in the absence of an indicator, wall clock time is assumed. +Local time and date is interpreted as of just before the rule takes effect. .TP .B SAVE Gives the amount of time to be added to local standard time when the rule is in
Okay, so if I've understood you correctly, the date are always as per the wall clock. The time *may* be specified in standard or UTC, but that doesn't affect how the date part is specified. So just to clarify with a strange example, consider this part of a rule: Apr Mon>=1 2:00u So say we're looking for the next transition after 2013-01-01T00:00:00Z, and the current UTC offset is -8. My interpretation of what you've said is that we first identify the local date (2013-04-01, which is a Monday) and then we find the point in time in that 24 hour period at which the UTC time is 02:00. So: Monday April 1st, 6pm local (before) Tuesday April 2nd, 2am UTC I'm pretty sure that Noda Time wouldn't handle that correctly :( Could you double check my example before I start fixing code? I think at the moment I always assume that the time of day and the date are in the same frame of reference - so in the above example, I suspect I'd find a transition at Monday April 1st, 2am UTC - a whole day early. I realize that all of this may be academic at the moment - I doubt that there are any rules specified which *do* have this sort of effect - but I'd rather know about bugs sooner rather than later. It might be an interesting example to try against other implementations, too... Jon On 7 July 2014 22:57, Paul Eggert <eggert@cs.ucla.edu> wrote:
Transitions are given in terms of the local time before the transition, as otherwise a transition could be self-referential. A single rule can specify multiple transitions, and it's reinterpreted each time it's used.
Perhaps the following change to zic.8?
diff --git a/zic.8 b/zic.8 index fb8f882..bd9dfeb 100644 --- a/zic.8 +++ b/zic.8 @@ -283,6 +283,7 @@ or if the given time is universal time; in the absence of an indicator, wall clock time is assumed. +Local time and date is interpreted as of just before the rule takes effect. .TP .B SAVE Gives the amount of time to be added to local standard time when the rule is in
On 7 July 2014 18:44, Jon Skeet <skeet@pobox.com> wrote:
I think at the moment I always assume that the time of day and the date are in the same frame of reference - so in the above example, I suspect I'd find a transition at Monday April 1st, 2am UTC
This, too, is my personal understanding of at least the *intent* behind the interpretation of years, months, and dates in FROM, TO, TYPE, IN, and ON, That is, they are to take the same interpretation as the suffix which applies to AT. In your example: Since 2:00u is specified for the transition, Apr Mon>=1 should be treated as Universal time, then find 02:00Z within that day. So transition Monday 1 April 02:00 UTC, which is Sunday 31 March 18:00 UTC–8. On 7 July 2014 17:57, Paul Eggert <eggert@cs.ucla.edu> wrote:
Transitions are given in terms of the local time before the transition, as otherwise a transition could be self-referential.
This doesn't seem it should apply to transition rules with "u"/"g"/"z" suffix; only those with "s" or "w"/no suffix. "Standard time" rules would be computed similarly to "Universal time" rules. Find the span of the specified date in the zone's standard time (as reckoned by the offset PRIOR to the transition), then find the specified standard time within that span. "Wall clock time" rules with no suffix (or a "w" suffix) would find the span of the date in the zone's wall clock time (as reckoned by the PRIOR offset), then find the proper wall clock time. I think this seems the most logical for maintenance and rule-writing, as any rule specified in, e.g., UTC, ought to recur in UTC. For a concrete example, see how current EU rules are meant to apply to America/Godthab. Transitions occur at Mar lastSun 1:00u and Oct lastSun 1:00u, which should be equivalent to Mar Sat>=24 22:00s and Oct Sat>=24 22:00s. -- Tim Parenti
Thanks for the fabulous example of Godthab. I've confirmed that http://www.timeanddate.com/time/zone/greenland/nuuk <http://timeanddate.com>, Noda Time and Java 8 all put the next transition at 2014-10-26T01:00:00Z, so 1am Sunday UTC, 11pm *Saturday *local time. So that's the first thing that should be clarified in the documentation, IMO - assuming that we're happy that *is* the correct behaviour. The next part - and where I started - is which year that transition would be assumed to be in. Sure, for October it's not a problem... but imagine the rule had been for the first Sunday in January, with a rule starting in 2012. When would the rule have first applied? Either it wouldn't have applied in 2012 at all, or it would have applied in *UTC* 2012, which was *local* 2011 at the point of the transition. Again, I realize this is mostly theoretical - if everyone's happy to agree that we just avoid getting to this edge condition (through careful rule crafting), that'd be great... but should also be documented, I think. Jon On 8 July 2014 01:15, Tim Parenti <tim@timtimeonline.com> wrote:
On 7 July 2014 18:44, Jon Skeet <skeet@pobox.com> wrote:
I think at the moment I always assume that the time of day and the date are in the same frame of reference - so in the above example, I suspect I'd find a transition at Monday April 1st, 2am UTC
This, too, is my personal understanding of at least the *intent* behind the interpretation of years, months, and dates in FROM, TO, TYPE, IN, and ON, That is, they are to take the same interpretation as the suffix which applies to AT.
In your example: Since 2:00u is specified for the transition, Apr Mon>=1 should be treated as Universal time, then find 02:00Z within that day. So transition Monday 1 April 02:00 UTC, which is Sunday 31 March 18:00 UTC–8.
On 7 July 2014 17:57, Paul Eggert <eggert@cs.ucla.edu> wrote:
Transitions are given in terms of the local time before the transition, as otherwise a transition could be self-referential.
This doesn't seem it should apply to transition rules with "u"/"g"/"z" suffix; only those with "s" or "w"/no suffix.
"Standard time" rules would be computed similarly to "Universal time" rules. Find the span of the specified date in the zone's standard time (as reckoned by the offset PRIOR to the transition), then find the specified standard time within that span.
"Wall clock time" rules with no suffix (or a "w" suffix) would find the span of the date in the zone's wall clock time (as reckoned by the PRIOR offset), then find the proper wall clock time.
I think this seems the most logical for maintenance and rule-writing, as any rule specified in, e.g., UTC, ought to recur in UTC.
For a concrete example, see how current EU rules are meant to apply to America/Godthab. Transitions occur at Mar lastSun 1:00u and Oct lastSun 1:00u, which should be equivalent to Mar Sat>=24 22:00s and Oct Sat>=24 22:00s.
-- Tim Parenti
On 8 July 2014 02:00, Jon Skeet <skeet@pobox.com> wrote:
The next part - and where I started - is which year that transition would be assumed to be in.
Again, I think the years themselves should be in the same frame-of-reference as the months and days, for the same reason. That is, to apply a rule: For each year between FROM and TO, inclusive (which matches TYPE), find the day-long span corresponding to the date specified by month IN and date ON within that year, according to the frame-of-reference (u/g/z/s/w/blank) specified in AT and the prior offset of the zone; then, find the transition time specified by AT within that span. If you'll indulge me for a moment, my brain refused to explain this to myself in a less silly way... Consider the scattered Kingdom of Foo, which straddles the Prime Meridian: Rule Foo 2012 max - Jan Sun>=1 1:00u 1 D Rule Foo 2012 max - Jul Sun>=1 1:00u 0 S Zone A-Land 1:00 Foo A%sT Zone B-Land -3:00 Foo B%sT One would imagine that the rules should take effect throughout the Kingdom simultaneously; that is, advance at 2012-01-01T01:00Z. In A-Land, this is Sun 1 Jan 2012 02:00 AST --> 03:00 ADT, but in B-Land, this is Sat 31 Dec *2011* 22:00 BST --> 23:00 BDT. It appears zic handles this correctly: $ zdump -vc 2012,2013 A-Land B-Land ... A-Land Sun Jan 1 00:59:59 2012 UT = Sun Jan 1 01:59:59 2012 AST isdst=0 A-Land Sun Jan 1 01:00:00 2012 UT = Sun Jan 1 03:00:00 2012 ADT isdst=1 A-Land Sun Jul 1 00:59:59 2012 UT = Sun Jul 1 02:59:59 2012 ADT isdst=1 A-Land Sun Jul 1 01:00:00 2012 UT = Sun Jul 1 02:00:00 2012 AST isdst=0 ... B-Land Sun Jan 1 00:59:59 2012 UT = Sat Dec 31 21:59:59 2011 BST isdst=0 B-Land Sun Jan 1 01:00:00 2012 UT = Sat Dec 31 23:00:00 2011 BDT isdst=1 B-Land Sun Jul 1 00:59:59 2012 UT = Sat Jun 30 22:59:59 2012 BDT isdst=1 B-Land Sun Jul 1 01:00:00 2012 UT = Sat Jun 30 22:00:00 2012 BST isdst=0 ... A similar case could be made for the equally-dispersed Bar Empire, which straddles the International Date Line: Rule Bar 2017 max - Jun lastSun 14:00u 1 D Rule Bar 2017 max - Dec lastSun 14:00u 0 S Zone X-Land -11:00 Bar X%sT Zone Y-Land 11:00 Bar Y%sT The transition to standard time should occur at 2017-12-31T14:00Z. In X-Land, Sun 31 Dec 2017 04:00 XDT --> 03:00 XST, but in Y-Land, Mon 1 Jan *2018* 02:00 YDT --> 01:00 YST. $ zdump -vc 2017,2018 X-Land Y-Land ... X-Land Sun Jun 25 13:59:59 2017 UT = Sun Jun 25 02:59:59 2017 XST isdst=0 X-Land Sun Jun 25 14:00:00 2017 UT = Sun Jun 25 04:00:00 2017 XDT isdst=1 X-Land Sun Dec 31 13:59:59 2017 UT = Sun Dec 31 03:59:59 2017 XDT isdst=1 X-Land Sun Dec 31 14:00:00 2017 UT = Sun Dec 31 03:00:00 2017 XST isdst=0 ... Y-Land Sun Jun 25 13:59:59 2017 UT = Mon Jun 26 00:59:59 2017 YST isdst=0 Y-Land Sun Jun 25 14:00:00 2017 UT = Mon Jun 26 02:00:00 2017 YDT isdst=1 Y-Land Sun Dec 31 13:59:59 2017 UT = Mon Jan 1 01:59:59 2018 YDT isdst=1 Y-Land Sun Dec 31 14:00:00 2017 UT = Mon Jan 1 01:00:00 2018 YST isdst=0 ... I agree these particular edge conditions are a bit ridiculous, and probably should be avoided anyway if possible, but it would be good to document the expected behavior here. (The citizens of Foo and Bar, who simply live for edge cases, will be grateful. And I can be sure of that because they are, thankfully, fictitious.) -- Tim Parenti
Arthuritatively speaking, the intent is that rules describe instants when a clock/calendar set to the type of time specified in the AT field would show the specified date and time of day. @dashdashado On Tue, Jul 8, 2014 at 6:24 PM, Tim Parenti <tim@timtimeonline.com> wrote:
On 8 July 2014 02:00, Jon Skeet <skeet@pobox.com> wrote:
The next part - and where I started - is which year that transition would be assumed to be in.
Again, I think the years themselves should be in the same frame-of-reference as the months and days, for the same reason. That is, to apply a rule: For each year between FROM and TO, inclusive (which matches TYPE), find the day-long span corresponding to the date specified by month IN and date ON within that year, according to the frame-of-reference (u/g/z/s/w/blank) specified in AT and the prior offset of the zone; then, find the transition time specified by AT within that span.
If you'll indulge me for a moment, my brain refused to explain this to myself in a less silly way...
Consider the scattered Kingdom of Foo, which straddles the Prime Meridian: Rule Foo 2012 max - Jan Sun>=1 1:00u 1 D Rule Foo 2012 max - Jul Sun>=1 1:00u 0 S Zone A-Land 1:00 Foo A%sT Zone B-Land -3:00 Foo B%sT
One would imagine that the rules should take effect throughout the Kingdom simultaneously; that is, advance at 2012-01-01T01:00Z. In A-Land, this is Sun 1 Jan 2012 02:00 AST --> 03:00 ADT, but in B-Land, this is Sat 31 Dec *2011* 22:00 BST --> 23:00 BDT. It appears zic handles this correctly:
$ zdump -vc 2012,2013 A-Land B-Land ... A-Land Sun Jan 1 00:59:59 2012 UT = Sun Jan 1 01:59:59 2012 AST isdst=0 A-Land Sun Jan 1 01:00:00 2012 UT = Sun Jan 1 03:00:00 2012 ADT isdst=1 A-Land Sun Jul 1 00:59:59 2012 UT = Sun Jul 1 02:59:59 2012 ADT isdst=1 A-Land Sun Jul 1 01:00:00 2012 UT = Sun Jul 1 02:00:00 2012 AST isdst=0 ... B-Land Sun Jan 1 00:59:59 2012 UT = Sat Dec 31 21:59:59 2011 BST isdst=0 B-Land Sun Jan 1 01:00:00 2012 UT = Sat Dec 31 23:00:00 2011 BDT isdst=1 B-Land Sun Jul 1 00:59:59 2012 UT = Sat Jun 30 22:59:59 2012 BDT isdst=1 B-Land Sun Jul 1 01:00:00 2012 UT = Sat Jun 30 22:00:00 2012 BST isdst=0 ...
A similar case could be made for the equally-dispersed Bar Empire, which straddles the International Date Line: Rule Bar 2017 max - Jun lastSun 14:00u 1 D Rule Bar 2017 max - Dec lastSun 14:00u 0 S Zone X-Land -11:00 Bar X%sT Zone Y-Land 11:00 Bar Y%sT
The transition to standard time should occur at 2017-12-31T14:00Z. In X-Land, Sun 31 Dec 2017 04:00 XDT --> 03:00 XST, but in Y-Land, Mon 1 Jan *2018* 02:00 YDT --> 01:00 YST.
$ zdump -vc 2017,2018 X-Land Y-Land ... X-Land Sun Jun 25 13:59:59 2017 UT = Sun Jun 25 02:59:59 2017 XST isdst=0 X-Land Sun Jun 25 14:00:00 2017 UT = Sun Jun 25 04:00:00 2017 XDT isdst=1 X-Land Sun Dec 31 13:59:59 2017 UT = Sun Dec 31 03:59:59 2017 XDT isdst=1 X-Land Sun Dec 31 14:00:00 2017 UT = Sun Dec 31 03:00:00 2017 XST isdst=0 ... Y-Land Sun Jun 25 13:59:59 2017 UT = Mon Jun 26 00:59:59 2017 YST isdst=0 Y-Land Sun Jun 25 14:00:00 2017 UT = Mon Jun 26 02:00:00 2017 YDT isdst=1 Y-Land Sun Dec 31 13:59:59 2017 UT = Mon Jan 1 01:59:59 2018 YDT isdst=1 Y-Land Sun Dec 31 14:00:00 2017 UT = Mon Jan 1 01:00:00 2018 YST isdst=0 ...
I agree these particular edge conditions are a bit ridiculous, and probably should be avoided anyway if possible, but it would be good to document the expected behavior here. (The citizens of Foo and Bar, who simply live for edge cases, will be grateful. And I can be sure of that because they are, thankfully, fictitious.)
-- Tim Parenti
Thanks, I applied the attached patch to get that clarification into the documentation.
participants (5)
-
Arthur David Olson -
David Braverman -
Jon Skeet -
Paul Eggert -
Tim Parenti