The description of the second Value function (returning Duration) (ARM 9.6.1(87)
doesn't place any limitation on the Elapsed_Time parameter's value, beyond
"Constraint_Error is raised if the string is not formatted as described for Image, or
the function cannot interpret the given string as a Duration value".
It would seem reasonable that Value and Image should be consistent, in that any
string produced by Image should be accepted by Value. Since Image must produce
a two-digit representation of the Hours, there's an implication that its
Elapsed_Time parameter should be less than 100.0 hours (the ARM merely says
that in that case the result is implementation-defined).
The current implementation of Value raises Constraint_Error if the Elapsed_Time
parameter is greater than or equal to 24 hours.
This patch removes the restriction, so that the Elapsed_Time parameter must only
be less than 100.0 hours.
2023-10-15 Simon Wright <simon@pushface.org>
PR ada/111813
gcc/ada/
* libgnat/a-calfor.adb (Value (2)): Allow values of
parameter Elapsed_Time greater than or equal to 24 hours, by doing
the hour calculations in Natural rather than Hour_Number (0 ..
23). Calculate the result directly rather than by using Seconds_Of
(whose Hour parameter is of type Hour_Number).
If an exception occurs of type Constraint_Error, re-raise it
rather than raising a new CE.
gcc/testsuite/
* gnat.dg/calendar_format_value.adb: New test.
function Value (Elapsed_Time : String) return Duration is
D : String (1 .. 11);
- Hour : Hour_Number;
+ Hour : Natural;
Minute : Minute_Number;
Second : Second_Number;
Sub_Second : Second_Duration := 0.0;
-- Value extraction
- Hour := Hour_Number (Hour_Number'Value (D (1 .. 2)));
+ Hour := Natural (Natural'Value (D (1 .. 2)));
Minute := Minute_Number (Minute_Number'Value (D (4 .. 5)));
Second := Second_Number (Second_Number'Value (D (7 .. 8)));
raise Constraint_Error;
end if;
- return Seconds_Of (Hour, Minute, Second, Sub_Second);
+ return Duration (Hour * 3600)
+ + Duration (Minute * 60)
+ + Duration (Second)
+ + Sub_Second;
exception
+ -- CE is mandated, but preserve trace if CE already.
+ when Constraint_Error => raise;
when others => raise Constraint_Error;
end Value;
--- /dev/null
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar.Formatting;
+
+procedure Calendar_Format_Value is
+ Limit : constant Duration
+ := 99 * 3600.0 + 59 * 60.0 + 59.0;
+begin
+ declare
+ Image : constant String := Ada.Calendar.Formatting .Image (Limit);
+ Image_Error : exception;
+ begin
+ if Image /= "99:59:59" then
+ raise Image_Error with "image: " & Image;
+ end if;
+ declare
+ Value : constant Duration := Ada.Calendar.Formatting.Value (Image);
+ Value_Error : exception;
+ begin
+ if Value /= Limit then
+ raise Value_Error with "duration: " & Value'Image;
+ end if;
+ end;
+ end;
+end Calendar_Format_Value;