Version 1.3 of ais/ai-00427.txt

Unformatted version of ais/ai-00427.txt version 1.3
Other versions for file ais/ai-00427.txt

!standard 9.6.1(1)          05-04-11 AI95-00427/02
!class amendment 05-04-10
!status work item 05-04-10
!status received 05-04-10
!priority High
!difficulty Easy
!subject Default parameters and Calendar operations
!summary
1 The parameters of Split are rearranged so that the parameter
Time_Zone is last.
2 The parameter Time_Zone of Seconds and Sub_Seconds is deleted.
3 Functions Year, Month and Day with a Time Zone parameter are added.
4 The range on the subtype Leap_Seconds_Count is removed.
5 The AARM note regarding Difference is replaced. A parenthetic remark
is added to the normative text to confirm that Seconds does not include leap seconds.
6 The range of Time_Offset is increased.
7 The ranges of possible values of the result of the function Sub_Second
and parameters Seconds and Sub_Second of Time_Of, Seconds_Of and Split are clarified.
!problem
A number of improvements to the additional time facilities of AI-351 are suggested.
The default parameter Time_Zone of three subprograms Split is the second parameter. This means that if the default is used then all the out parameters which follow it have to use named notation. Since there are 5, 7 and 8 of these, this is tiresome.
The result of the functions Second and Sub_Second cannot depend upon the parameter Time_Zone which is therefore superfluous.
There are no functions Year, Month and Day with a time zone parameter, this forces the use of Split.
The AARM note regarding difference is peculiar.
The facilities of these packages enable the decomposition of a Time "as appropriate for the time offset specified". This enables a program running with a local Clock to decompose a time as UTC. It also enables a program to decompose a local time as if in some other time zone. Thus in New York we can get the time decomposed as if in Paris by a Time Offset of -360. But it won't work for a program running in local time in Tonga and wanting the time in the Aleutian Islands because of the vagaries of the International Date Line. The time shift is 25 hours and this exceeds the range of Time_Offset. Even larger shifts are possible.
The text 9.6 (26) referring to Split and Time_Of in Calendar prescribes the behavior regarding a Seconds value of 86_400.0. There is no corresponding text regarding the subprograms in the child package for Seconds or Sub_Second.
!proposal
(See summary.)
!wording
Change 9.6.1(4/2) to
type Time_Offset is range -1680 .. 1680; -- allows 28 hours
Replace 9.6.1(11/2) by
subtype Leap_Seconds_Count is Integer range -2047 .. 2047;
Add after 9.6.1(23/2)
function Year (Date : Time; Time_Zone : Time_Zones.Time_Offset := 0) return Year_Number;
function Month (Date : Time; Time_Zone : Time_Zones.Time_Offset := 0) return Month_Number;
function Day (Date : Time; Time_Zone : Time_Zones.Time_Offset := 0) return Day_Number;
Replace 9.6.1(26/2-27/2) by
function Second (Date : Time) return Second_Number;
function Sub_Second (Date : Time) return Second_Duration;
Replace 9.6.1(30/2) by
procedure Split (Date : in Time; Year : out Year_Number; Month : out Month_Number; Day : out Day_Number; Hour : out Hour_Number; Minute : out Minute_Number; Second : out Second_Number; Sub_Second : out Second_Duration; Time_Zone : in Time_Zones.Time_Offset := 0);
Replace 9.6.1(33/2-34/2) by
procedure Split (Date : in Time; Year : out Year_Number; Month : out Month_Number; Day : out Day_Number; Hour : out Hour_Number; Minute : out Minute_Number; Second : out Second_Number; Sub_Second : out Second_Duration; Leap_Second: out Boolean; Time_Zone : in Time_Zones.Time_Offset := 0);
procedure Split (Date : in Time; Year : out Year_Number; Month : out Month_Number; Day : out Day_Number; Seconds : out Day_Duration; Leap_Second: out Boolean; Time_Zone : in Time_Zones.Time_Offset := 0);
Change 9.6.1 (44/2) thus
Returns the difference between Left and Right. Days is the number of days of difference, Seconds is the remainder seconds of difference {excluding leap seconds}, and Leap_Seconds is the number of leap seconds. If Left < Right, then Seconds <= 0.0, Days <= 0, and Leap_Seconds <= 0. Otherwise, all values are non-negative. {The absolute value of Seconds is always less than 86_400.0.} For the returned values, if Days = 0, then Seconds + Duration(Leap_Seconds) = Calendar."-" (Left, Right).
Change 9.6.1 (44.a/2) thus
[The number of days is calculated midnight-to-midnight.] Leap_Seconds, if any, are not included in Seconds.
Note: the above remark about leap seconds is really superfluous because it is now in the normative text but it leads into the next AARM paragraph neatly.
Add at the end of 9.6.1 (60/2)
The value returned is always less than 1.0.
Add at the end of 9.6.1 (62/2)
If Seconds_Of is called with a Sub_Second value of 1.0, the value returned is equal to the value of Seconds_Of for the next second with a Sub_Second value of 0.0.
Add at the end of 9.6.1 (64/2)
The value returned through the Sub_Second parameter is always less than 1.0.
Add at the end of 9.6.1 (66/2)
The value returned through the Sub_Second parameter is always less than 1.0.
Add at the end of 9.6.1 (68/2)
If Time_Of is called with a Sub_Second value of 1.0, the value returned is equal to the value of Time_Of for the next second with a Sub_Second value of 0.0.
Add at the end of 9.6.1 (70/2)
If Time_Of is called with a Seconds value of 86_400.0, the value returned is equal to the value of Time_Of for the next day with a Seconds value of 0.0.
Add at the end of 9.6.1 (72/2)
The value returned through the Sub_Second parameter is always less than 1.0.
Add at the end of 9.6.1 (74/2)
The value returned through the Seconds parameter is always less than 86_400.0.
!discussion
This subject is a can of worms, basket of snakes, or boite de Pandore (French being posh again).
Although in parameters are usually given before out parameters, it is much more convenient for the user for defaulted parameters to be last. There is an example in the package Interfaces.C. The procedures To_C and To_Ada have an in parameter with defaults after some out parameters. It is therefore proposed that the procedures Split be changed.
The functions Second and Sub_Second currently have a parameter Time_Zone. However, since the time zone is defined by a number of minutes the values returned by Second and Sub_Second cannot depend upon the parameter. The parameter should therefore be removed. It has been argued that these functions are implemented by a call of Split and that needs a parameter, but the default value of zero can be used.
Functions Hour and Minute are provided with a time zone parameter to enable the correct values to be returned. However, there are no similar functions Year, Month and Day. It is of course possible to use Split but why provide Hour and Minute in that case since they can be done the same way?
The range on the subtype Leap_Second is -999 .. 999. This is arbitrary. In practice the values of this subtype that will arise will be less than 100. However, in principle there could be a leap second every quarter and since there were 32 between 1901 and now the maximum possible value is
32 + 4 * (2399 - 2005 + 1) = 1612
The real advantage in having a range constraint is that it gives some guidance to an implementation regarding how many bits to allow for this information. Accordingly the range is made -2047 .. 2047. A nice dozen bits.
The note regarding Difference says "The number of days is calculated midnight-to-midnight". The draft rationale notes "Maybe it means that if I take the difference between 1am on Monday and 11pm on Wednesday then I get just one day (midnight Monday to midnight Tuesday) and then the seconds would be for 46 hours which could overflow Duration." Clearly this note must be a hangover from some previous incarnation. It should be removed. Some clarification might be helpful however. The formula given in 9.6.1(44/2), namely
if Days = 0 then Seconds + Duration(Leap_Seconds) = Calendar."-"(Left, Right)
sort of does this by implying that the leap seconds are accounted for in Leap_Sconds) and not in Seconds. An existing AARM note confirms this. This note has been strengthened by a parenthetic remark in the normative text. Note that this formula says nothing about what happens if Days /= 0.
It also confirms that Calendar."-" returns 86401 for the difference between the same time on successive days if there was a leap second. Thus
Calendar."-"(Time_Of(1985, 7, 1, 0.0), Time_Of(1985, 6, 30, 0.0))
for a program in Paris using the local clock returns 86401 seconds because of the leap second at 10pm local time (heure d'ete) on 30 June 1985.
So we need to add that the absolute value of Seconds produced by Difference is never 86_400.0.
Also we need to add somewhere that for three functions Split the out parameter Sub_Second is never 1.0, and for the other Split the out parameter Seconds is never 86_400.0. Also that if Time_Of or Seconds_Of is given a parameter 1.0 for Sub_Second then the time constructed is for the next Second and that if the other Time_Of is given a parameter 86_400.0 for Seconds then the time constructed is for the next day. Finally, we need to add that the function Sub_Second never returns 1.0. The corresponding information for the package Calendar is all in 9.6(25). It has been added to the discussion for each subprogram which is tedious but clear.
As explained in the proposal section, the vagaries of the International Date Line means that locations can have more than a relative 24 hour time offset. Moreover, locations in opposite hemispheres can have daylight saving in opposite directions. The range of Time Offset is therefore increased to 28 hours which is generous but surely enough.
There is one other anomaly that this AI does not address. There is no procedure Split which delivers Year, Month, Day and Seconds but not Leap_Seconds and has a parameter Time_Zone. This is perhaps because the procedure Calendar.Split already has no Leap Seconds parameter. But that has no Time_Zone and so the combinations are not complete. Yet another Split could be added making 5 in the package Formatting. It might be an improvement to change the identifier of the Split acting on Seconds to something else anyway, say, Split_Seconds. At least that would make some differentiation.
!example
(See discussion.)
--!corrigendum
!ACATS test
!appendix

*************************************************************

Questions? Ask the ACAA Technical Agent