diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-08 06:46:17 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-08 06:46:17 +0000 |
commit | 264aeddecba1a2acb8a2c5da16401302097950dd (patch) | |
tree | ca7f3ae4a9adaf9b0a82411a7847979c11d518c3 /gcc/ada/a-calend.adb | |
parent | 8b29235c563e2f7d80708200d851a234416cab60 (diff) | |
download | gcc-264aeddecba1a2acb8a2c5da16401302097950dd.tar.gz |
2008-04-08 Hristian Kirtchev <kirtchev@adacore.com>
* a-calend-vms.ads, a-calend-vms.adb: Add with and use clause for
System.OS_Primitives.
Change type of various constants, parameters and local variables from
Time to representation type OS_Time.
(To_Ada_Time, To_Unix_Time): Correct sign of origin shift.
Remove the declaration of constant Mili_F from several routines. New
body for internal package Conversions_Operations.
(Time_Of): Add default parameters for several formals.
* a-caldel.adb: Minor reformatting
* a-calend.ads, a-calend.adb: New body for internal package
Conversions_Operations.
(Time_Of): Add default parameters for several formals.
* Makefile.rtl: Add a-ststop
Add Ada.Calendar.Conversions to the list of runtime files.
Add g-timsta
* a-calcon.adb, a-calcon.ads: New files.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134014 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/a-calend.adb')
-rw-r--r-- | gcc/ada/a-calend.adb | 218 |
1 files changed, 212 insertions, 6 deletions
diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb index 1fe977d68a4..2e7c61a9d7f 100644 --- a/gcc/ada/a-calend.adb +++ b/gcc/ada/a-calend.adb @@ -758,13 +758,216 @@ package body Ada.Calendar is when Constraint_Error => raise Time_Error; end Subtract; + end Arithmetic_Operations; + --------------------------- + -- Conversion_Operations -- + --------------------------- + + package body Conversion_Operations is + + Epoch_Offset : constant Time_Rep := + (136 * 365 + 44 * 366) * Nanos_In_Day; + -- The difference between 2150-1-1 UTC and 1970-1-1 UTC expressed in + -- nanoseconds. Note that year 2100 is non-leap. + + ----------------- + -- To_Ada_Time -- + ----------------- + + function To_Ada_Time (Unix_Time : Long_Integer) return Time is + pragma Unsuppress (Overflow_Check); + Unix_Rep : constant Time_Rep := Time_Rep (Unix_Time) * Nano; + begin + return Time (Unix_Rep - Epoch_Offset); + exception + when Constraint_Error => + raise Time_Error; + end To_Ada_Time; + + ----------------- + -- To_Ada_Time -- + ----------------- + + function To_Ada_Time + (tm_year : Integer; + tm_mon : Integer; + tm_day : Integer; + tm_hour : Integer; + tm_min : Integer; + tm_sec : Integer; + tm_isdst : Integer) return Time + is + pragma Unsuppress (Overflow_Check); + Year : Year_Number; + Month : Month_Number; + Day : Day_Number; + Second : Integer; + Leap : Boolean; + Result : Time_Rep; + + begin + -- Input processing + + Year := Year_Number (1900 + tm_year); + Month := Month_Number (1 + tm_mon); + Day := Day_Number (tm_day); + + -- Step 1: Validity checks of input values + + if not Year'Valid + or else not Month'Valid + or else not Day'Valid + or else tm_hour not in 0 .. 24 + or else tm_min not in 0 .. 59 + or else tm_sec not in 0 .. 60 + or else tm_isdst not in -1 .. 1 + then + raise Time_Error; + end if; + + -- Step 2: Potential leap second + + if tm_sec = 60 then + Leap := True; + Second := 59; + else + Leap := False; + Second := tm_sec; + end if; + + -- Step 3: Calculate the time value + + Result := + Time_Rep + (Formatting_Operations.Time_Of + (Year => Year, + Month => Month, + Day => Day, + Day_Secs => 0.0, -- Time is given in h:m:s + Hour => tm_hour, + Minute => tm_min, + Second => Second, + Sub_Sec => 0.0, -- No precise sub second given + Leap_Sec => Leap, + Use_Day_Secs => False, -- Time is given in h:m:s + Is_Ada_05 => True, -- Force usage of explicit time zone + Time_Zone => 0)); -- Place the value in UTC + + -- Step 4: Daylight Savings Time + + if tm_isdst = 1 then + Result := Result + Time_Rep (3_600) * Nano; + end if; + + return Time (Result); + + exception + when Constraint_Error => + raise Time_Error; + end To_Ada_Time; + + ----------------- + -- To_Duration -- + ----------------- + + function To_Duration + (tv_sec : Long_Integer; + tv_nsec : Long_Integer) return Duration + is + pragma Unsuppress (Overflow_Check); + begin + return Duration (tv_sec) + Duration (tv_nsec) / Nano_F; + end To_Duration; + + ------------------------ + -- To_Struct_Timespec -- + ------------------------ + + procedure To_Struct_Timespec + (D : Duration; + tv_sec : out Long_Integer; + tv_nsec : out Long_Integer) + is + pragma Unsuppress (Overflow_Check); + Secs : Duration; + Nano_Secs : Duration; + + begin + -- Seconds extraction, avoid potential rounding errors + + Secs := D - 0.5; + tv_sec := Long_Integer (Secs); + + -- Nanoseconds extraction + + Nano_Secs := D - Duration (tv_sec); + tv_nsec := Long_Integer (Nano_Secs * Nano); + end To_Struct_Timespec; + + ------------------ + -- To_Struct_Tm -- + ------------------ + + procedure To_Struct_Tm + (T : Time; + tm_year : out Integer; + tm_mon : out Integer; + tm_day : out Integer; + tm_hour : out Integer; + tm_min : out Integer; + tm_sec : out Integer) + is + pragma Unsuppress (Overflow_Check); + Year : Year_Number; + Month : Month_Number; + Second : Integer; + Day_Secs : Day_Duration; + Sub_Sec : Duration; + Leap_Sec : Boolean; + + begin + -- Step 1: Split the input time + + Formatting_Operations.Split + (T, Year, Month, tm_day, Day_Secs, + tm_hour, tm_min, Second, Sub_Sec, Leap_Sec, True, 0); + + -- Step 2: Correct the year and month + + tm_year := Year - 1900; + tm_mon := Month - 1; + + -- Step 3: Handle leap second occurences + + if Leap_Sec then + tm_sec := 60; + else + tm_sec := Second; + end if; + end To_Struct_Tm; + + ------------------ + -- To_Unix_Time -- + ------------------ + + function To_Unix_Time (Ada_Time : Time) return Long_Integer is + pragma Unsuppress (Overflow_Check); + Ada_Rep : constant Time_Rep := Time_Rep (Ada_Time); + begin + return Long_Integer ((Ada_Rep + Epoch_Offset) / Nano); + exception + when Constraint_Error => + raise Time_Error; + end To_Unix_Time; + end Conversion_Operations; + ---------------------- -- Delay_Operations -- ---------------------- - package body Delays_Operations is + package body Delay_Operations is ----------------- -- To_Duration -- @@ -804,7 +1007,8 @@ package body Ada.Calendar is return Time (Res_N) - Time (Unix_Min); end To_Duration; - end Delays_Operations; + + end Delay_Operations; --------------------------- -- Formatting_Operations -- @@ -1071,10 +1275,10 @@ package body Ada.Calendar is Minute : Integer; Second : Integer; Sub_Sec : Duration; - Leap_Sec : Boolean; - Use_Day_Secs : Boolean; - Is_Ada_05 : Boolean; - Time_Zone : Long_Integer) return Time + Leap_Sec : Boolean := False; + Use_Day_Secs : Boolean := False; + Is_Ada_05 : Boolean := False; + Time_Zone : Long_Integer := 0) return Time is Count : Integer; Elapsed_Leaps : Natural; @@ -1217,6 +1421,7 @@ package body Ada.Calendar is return Time (Res_N); end Time_Of; + end Formatting_Operations; --------------------------- @@ -1352,6 +1557,7 @@ package body Ada.Calendar is return Offset; end UTC_Time_Offset; + end Time_Zones_Operations; -- Start of elaboration code for Ada.Calendar |