summaryrefslogtreecommitdiff
path: root/gcc/ada/a-calend.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-08 06:46:17 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-08 06:46:17 +0000
commit264aeddecba1a2acb8a2c5da16401302097950dd (patch)
treeca7f3ae4a9adaf9b0a82411a7847979c11d518c3 /gcc/ada/a-calend.adb
parent8b29235c563e2f7d80708200d851a234416cab60 (diff)
downloadgcc-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.adb218
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