CVS difference for ai12s/ai12-0336-1.txt
--- ai12s/ai12-0336-1.txt 2019/06/05 04:00:22 1.1
+++ ai12s/ai12-0336-1.txt 2019/06/07 02:54:19 1.2
@@ -1,4 +1,4 @@
-!standard 9.6.1(40/2) 19-06-04 AI12-0336-1/01
+!standard 9.6.1(40/2) 19-06-06 AI12-0336-1/02
!standard 9.6.1(42/3)
!class binding interpretation 19-06-04
!status work item 19-06-04
@@ -33,23 +33,51 @@
!wording
+Add after 9.6.1(6/2):
+
+ function Local_Time_Offset (Date : Time := Clock) return Time_Offset
+ renames UTC_Time_Offset;
+
+Add after 9.6.1(35/2):
+
+ function Local_Image (Date : Time;
+ Include_Time_Fraction : Boolean := False) return String is
+ (Image (Date, Include_Time_Fraction, Local_Time_Offset (Date)));
+
Modify 9.6.1(40/2):
-{For the purposes of this subclause, the /time zone/ for a
-given locality is defined in terms of the number of minutes
-the local time is ahead (+) or behind (-) Coordinated Universal Time
-(abbreviated UTC).} Type Time_Offset represents the number of minutes
-difference between the implementation-defined time zone used by Calendar
-and another time zone.{Redundant[ The zero value of type Time_Offset
-represents the implementation-defined time zone of Calendar.]}
+Type Time_Offset represents {for a given locality at a given moment} the
+number of minutes {the local time is,
+at that moment, ahead (+) or behind (-) Coordinated Universal Time
+(abbreviated UTC). Redundant[ The zero value
+of type Time_Offset represents UTC}
+[difference between UTC the implementation-defined time zone used
+by Calendar and another time zone].
Modify 9.6.1(42/3):
-Returns, as a number of minutes, [the result of subtracting]
-the implementation-defined time zone of Calendar [from UTC
+Returns, as a number of minutes, {the Time_Offset of}[the result of
+subtracting] the implementation-defined time zone of Calendar [from UTC
time], at the time Date. If the time zone of the Calendar
implementation is unknown, then Unknown_Zone_Error is raised.
+Delete the second sentence of AARM 9.6.1(42.a/2).
+
+Modify 9.6.1(90/2):
+
+The implementation-defined time zone of package Calendar may, but need not,
+be the local time zone. {Local}[UTC]_Time_Offset always returns the difference
+relative to the implementation-defined time zone of package Calendar. If
+{Local}[UTC]_Time_Offset does not raise Unknown_Zone_Error, UTC time can be
+safely calculated (within the accuracy of the underlying time-base).
+
+Modify 9.6.1(91/2):
+
+Calling Split on the results of subtracting
+Duration({Local}[UTC]_Time_Offset*60) from Clock provides the components
+(hours, minutes, and so on) of the UTC time. In the United States, for example,
+{Local}[UTC]_Time_Offset will generally be negative.
+
!discussion
As the questioner states, AI05-0119-1 clearly states that UTC_Time_Offset
@@ -64,6 +92,61 @@
not well-defined, so we have to talk about subtracting times in particular
time zones.
+----
+
+In researching this question, we tried a program provided by the questioner
+on all of the Ada 2005 compilers that we are aware of. All of the compilers
+that implement Ada.Calendar.Formatting except one (the least used one,
+still in beta) treated Time_Offset = 0 as UTC time.
+
+Enforcing the RM as written would therefore break any existing code that
+uses Ada.Calendar.Formatting (with the exception of the author's program
+that triggered this discussion).
+
+We therefore redefine Time_Offset to match the compilers, and add versions
+of some of the functions that provide the originally intended functionality.
+
+We used the prefix "Local_" to represent times for the "implementation-defined
+time zone of Calendar". Formally, since the time zone of Calendar need not be
+local, the correct name would be something like:
+
+ Implementation_Defined_Time_Zone_of_Calendar_Image (...)
+
+But this appears to have a small usability problem. :-) The original intent
+was that Image would do this, and we don't want to have to write too much more
+to get that original intent.
+
+We added a renamed version of UTC_Time_Offset names Local_Time_Offset, as that
+better represents the meaning of the function with the change in the definition
+of Time_Offset. Note that the actual result of the function is unchanged.
+
+We also added Local_Image, to provide the image of the Ada.Calendar time
+without having to call Local_Time_Offset.
+
+We considered defining Local_xxx versions of all of the other subprograms in
+Ada.Calendar.Formatting that take Time_Zone parameters.
+
+For Value and Time_Of, there is a problem: the correct time zone
+to use could depend on the result of the function -- which of course depends
+on the time zone passed in. For most uses, this is unlikely to be an issue,
+so we could define a version based on the current time zone, but that could
+get incorrect answers near a time zone change. (To get certain correct answers,
+one could iterate until the result was the same for two successive iterations,
+but such an iteration is not guaranteed to terminate, so it's impractical to
+use it in the language definition).
+
+We did not define new versions of Split in part because we aren't defining
+most of the other routines (as noted above), and simply because there are three
+versions with a bunch of parameters each, so these definitions would add quite
+a bit of text to the package. Local_Year, Local_Month, and so on don't seem
+useful enough to define.
+
+======
+
+Note again that this change is inconsistent with the Ada 2012 definition.
+So far as we are aware, only the beta 3.2.1 Janus/Ada follows the Ada 2012
+definition, so this inconsistency is not going to arise in practice.
+
!ASIS
No ASIS effect.
@@ -293,6 +376,129 @@
****************************************************************
+From: Joey Fish
+Sent: Wednesday, June 5, 2019 4:03 AM
+
+>This doesn't work for me. You are implying that the value of time is
+>time-zone dependent. That is not true on any Unix-like system.
+
+Why is this an issue? Why should the Ada standard's notion of time be at all
+linked to Unix? [or Windows, or VMS, or anything?]
+
+In fact, some of the biggest warts are due to importing and accommodating
+unix/c follies, with anonymous access types leading the charge.
+
+>I think we need to talk about the number of minutes since the local
+>midnight, say, and do the computation in terms of that value, perhaps
+>modulo 24*60.
+
+I'm not sure that is a good idea. (I'm currently working night-shift, so I
+come in and work before midnight and finish after midnight; so while it's
+simple to say "I worked 10 hours" denoting them in "minutes since [local]
+midnight" wouldn't be very nice.)
+
+I do know ISO 8601 was recently updated, perhaps looking at that would be
+helpful.
+
+****************************************************************
+
+From: Thomas Quinot
+Sent: Wednesday, June 5, 2019 4:27 AM
+
+> Modify 9.6.1(40/2):
+>
+> {For the purposes of this subclause, the /time zone/ for a given locality
+> is defined in terms of the number of minutes the local time is ahead (+)
+> or behind (-) UTC.} Type Time_Offset represents the number of minutes
+> difference between the implementation-defined time zone used by Calendar
+> and another time zone.
+
+However keep in mind that if you understand time zone as a single UTC offset
+then this depends not just on the locality but also on the specific point in
+time, due to daylight saving time issues. (IOW the UTC offset is a function
+of both the locality **and the point in tiem**).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, June 5, 2019 7:12 AM
+
+>> Modify 9.6.1(40/2):
+>>
+>> {For the purposes of this subclause, the /time zone/ for a given locality
+>> is defined in terms of the number of minutes the local time is ahead (+)
+>> or behind (-) UTC.} Type Time_Offset represents the number of minutes
+>> difference between the implementation-defined time zone used by Calendar
+>> and another time zone.
+>
+> However keep in mind that if you understand time zone as a single UTC
+> offset then this depends not just on the locality but also on the
+> specific point in time, due to daylight saving time issues. (IOW the
+> UTC offset is a function of both the locality **and the point in
+> tiem**).
+
+Good point. That should probably be more explicit, as it is in the
+definition of UTC_Time_Offset. Perhaps:
+
+{For the purposes of this subclause, the /time zone/ for a given locality at
+a given moment is defined in terms of the number of minutes the local time is,
+at that moment, ahead (+) or behind (-) UTC.}
+
+****************************************************************
+
+From: Dirk Craeynest
+Sent: Wednesday, June 5, 2019 4:32 AM
+
+> > We probably should start by defining what we mean by "time
+> > zone" since the term is used repeatedly. If that definition
+> > is described, for the purposes of this section, as a number
+> > of minutes the local time is ahead of (+) or behind (-) UTC,
+> > then I think the rest becomes trivial.
+> >
+> > Here is my attempt:
+> >
+> > Modify 9.6.1(40/2):
+> >
+> > {For the purposes of this subclause, the /time zone/ for a
+> > given locality is defined in terms of the number of minutes
+> > the local time is ahead (+) or behind (-) UTC.} Type
+> > Time_Offset represents the number of minutes difference
+> > between the implementation-defined time zone used by Calendar
+> > and another time zone.
+
+> The (minor) problem here is that type Time_Offset and the virtual
+> type time zone are very different for no obvious reason. [...]
+
+The definition proposed above is not what is commonly understood by "time
+zone" (a region with uniform time), but is a value: the time offset in that
+region versus UTC.
+
+Hence using UTC_Time_Offset or UTC_Offset for this value is probably more
+appropriate. And that value could then be of type Time_Offset...
+
+(See also https://en.wikipedia.org/wiki/List_of_UTC_time_offsets.)
+
+About:
+> Times would work slightly better if UTC was the default time zone
+
+Note that strictly speaking UTC is not a time zone: it is a time standard
+(Coordinated Universal Time).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, June 5, 2019 3:00 PM
+
+> Hence using UTC_Time_Offset or UTC_Offset for this value is probably
+> more appropriate. And that value could then be of type Time_Offset...
+
+I was trying to minimize wording changes here, since we are just fixing a bug.
+The existing wording uses the term "time zone" without defining it, and that
+has led to some confusion. We could reword this whole section probably, but I
+don't think that is justified to just fix this current bug.
+
+****************************************************************
+
!topic Time_Zone parameter to Calendar.Formatting subprograms
!reference Ada 2012 AARM 9.6.1
!from Simon Wright 2019-05-30
@@ -631,5 +837,180 @@
Wonder what ObjectAda does?
-***************************************************************
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 5, 2019 6:31 PM
+
+> Wonder what ObjectAda does?
+I sent PTC and Irvine this program (being the only other Ada 2005 compilers I
+know of).
+
+Irvine responded that they don't implement Ada.Calendar.Formatting.
+
+PTC sent a bunch of test results (in pretty screen grabs that I can't
+reasonably reproduce here). They pointed out that Simon had used the
+Object'Image, which is only a Ada 2012/TC1 feature. After fixing that
+problem, they reported the following results (hand keyed from the graphics,
+so if they don't make sense, blame me, not PTC).
+
+For ObjectAda 10.1:
+
+[...]> date
+Wed Jun 5 10:29:48 PDT 2019
+[...]> time_zone.exe
+
+UTC_Time_Offset: -420
+Time_Zone default: 2019-06-05 17:29:52
+Time_Zone offset: 2019-06-05 10:29:52
+
+----
+
+For ApexAda v5.2:
+
+[...]$ date
+Wed Jun 5 12:49:48 EDT 2019
+[...]$ ./timezone
+UTC_Time_Offset: -480
+Time_Zone default: 2019-06-05 12:49:55
+Time_Zone offset: 2019-06-05 04:49:55
+
+They also ran a copy of the ObjectAda program in France, giving:
+
+[...]> date
+Wed Jun 5 10:29:48 PDT 2019
+[...]> time_zone.exe
+
+UTC_Time_Offset: 120
+Time_Zone default: 2019-06-05 08:49:07
+Time_Zone offset: 2019-06-05 10:49:07
+
+=========================================================
+
+Conclusion: I'm apparently the only one that actually read the RM definition
+and implemented it exactly. Everyone else implemented the Time_Zone value as
+being an offset from UTC, or didn't implement it at all.
+
+Given the disruption inherent in forcing almost every compiler to change to
+the intended definition (which would break any existing code that is expecting
+a particular result, other than mine!), I think we have no choice but to
+revise the definition of Time_Offset to match that Tucker called "time zone".
+
+This is annoying in that the intent was that the default for Image would be
+the local time (not UTC). Short of adding additional routines, though, I don't
+see a way to do that and also change the RM meaning of Time_Offset.
+
+So, I would propose the following changes:
+
+(1) Change the definition of Time_Offset to match that Tucker used for
+ "time zone". We probably could drop that definition.
+(2) Add a renaming of UTC_Time_Offset called Local_Time_Offset (which is a
+ better name for this concept after the inversion of the meaning of
+ Time_Offset).
+(3) Add Local_Image, which would be defined to be Image (Time,
+ Include_Time_Fraction, Local_Time_Offset(Time));
+
+Perhaps we should add a matching Local_Value, but that's problematical to
+define as the time offset to use possibly depends on the result. (It's much
+less likely to be a problem in practice, so maybe some English definition is
+enough.)
+
+I don't think it pays to add Local_ versions of all of the Time_Of and Split
+routines, as there are five of them (and the definition of Local_Time_Of
+would have the same problem as Local_Value).
+
+What do you all think???
+
+****************************************************************
+
+From: Joey Fish
+Sent: Thursday, June 6, 2019 3:49 AM
+
+> This is annoying in that the intent was that the default for Image would be
+> the local time (not UTC). Short of adding additional routines, though, I
+> don't see a way to do that and also change the RM meaning of Time_Offset.
+
+I think the image should be in local time, isn't that [messing around with UTC
+and such] what the formatting/time_zones/conversion children of Ada.Calendar
+are about?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, June 6, 2019 12:53 PM
+
+Perhaps we could add a default for UTC_Time_Offset/Local_Time_Offset to be
+Calendar.Clock? Then you can just write "Local_Time_Offset" and use it as a
+default on a renaming of some of these routines to be Local_*.
+
+Too bad this was so unclear to begin with, but it sounds like there couldn't
+have been much use of these features so far, given the semi-random results
+that are produced.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 6, 2019 3:10 PM
+
+> Perhaps we could add a default for
+> UTC_Time_Offset/Local_Time_Offset to be Calendar.Clock?
+
+That *is* the default to UTC_Time_Offset.
+
+> Then
+> you can just write "Local_Time_Offset" and use it as a default on a
+> renaming of some of these routines to be Local_*.
+
+I thought of that, but it would be wrong for Local_Image and the like, as it
+wouldn't take into account time zone changes (i.e. summer/daylight saving
+time) for some times. For *inbound* times, it seems nasty to get the time
+zone wrong just so we can write a renaming. After all, the reason for having
+a time parameter is to avoid that sort of glitch. (And since Clock is
+relatively expensive, it probably would be faster to use the passed in time
+-- not that that would often matter.)
+
+We could do that for *outbound* items (Value and Time_Of), should we try to
+support those.
+
+> Too bad this was so unclear to begin with, but it sounds like there
+> couldn't have been much use of these features so far, given the
+> semi-random results that are produced.
+
+Well, all of the compilers 'cept mine do the same thing (and mine hasn't been
+released yet), so its probably the case that most users got a surprising
+answer once, changed their code, and moved on. This probably never would have
+shown up had I not created a library that actually followed the RM and then
+used it in a publicly posted program. When someone (Simon) tried to use the
+program on GNAT, then the difference showed up, and Simon was good enough to
+raise it here (I don't know that I would have).
+
+So it's quite possible this stuff is used a decent amount, just with a
+different expectation than the RM has.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 6, 2019 8:33 PM
+
+>>This is annoying in that the intent was that the default for Image would be
+>>the local time (not UTC). Short of adding additional routines, though,
+>>I don't see a way to do that and also change the RM meaning of Time_Offset.
+
+>I think the image should be in local time, isn't that [messing around
+>with UTC and such] what the formatting/time_zones/conversion children
+>of Ada.Calendar are about?
+
+True, but we also have an obligation to standardize existing practice when
+possible. Do we want to break everyone's code in this area?
+
+I'm suggesting that we split the baby by defining Local_Image to give the
+Calendar result and leave the existing Image to do what it does on all of the
+existing compilers except mine. (And note that Image is already in the
+"formatting/time_zones/conversion children of Ada.Calendar"; we're not talking
+about any change to Ada.Calendar.) It's not perfect but it is the least
+disruptive option. (It also would allow Ada runtimes to represent Time
+primarily in UTC time internally; I suspect that is the cause of this
+confusion.)
+
+***************************************************************
Questions? Ask the ACAA Technical Agent