OSDN Git Service

2011-12-02 Thomas Quinot <quinot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-calend-vms.adb
index c115c8a..788ff28 100644 (file)
@@ -6,25 +6,23 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2007, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
--- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
 --                                                                          --
--- As a special exception,  if other files  instantiate  generics from this --
--- unit, or you link  this unit with other files  to produce an executable, --
--- this  unit  does not  by itself cause  the resulting  executable  to  be --
--- covered  by the  GNU  General  Public  License.  This exception does not --
--- however invalidate  any other reasons why  the executable file  might be --
--- covered by the  GNU Public License.                                      --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 
 --  This is the Alpha/VMS version
 
-with System.Aux_DEC; use System.Aux_DEC;
-
 with Ada.Unchecked_Conversion;
 
+with System.Aux_DEC;       use System.Aux_DEC;
+with System.OS_Primitives; use System.OS_Primitives;
+
 package body Ada.Calendar is
 
    --------------------------
@@ -48,7 +47,7 @@ package body Ada.Calendar is
 
    --  Because time is measured in different units and from different origins
    --  on various targets, a system independent model is incorporated into
-   --  Ada.Calendar. The idea behing the design is to encapsulate all target
+   --  Ada.Calendar. The idea behind the design is to encapsulate all target
    --  dependent machinery in a single package, thus providing a uniform
    --  interface to all existing and any potential children.
 
@@ -77,21 +76,21 @@ package body Ada.Calendar is
    -- Local Subprograms --
    -----------------------
 
-   procedure Check_Within_Time_Bounds (T : Time);
+   procedure Check_Within_Time_Bounds (T : OS_Time);
    --  Ensure that a time representation value falls withing the bounds of Ada
    --  time. Leap seconds support is taken into account.
 
    procedure Cumulative_Leap_Seconds
-     (Start_Date    : Time;
-      End_Date      : Time;
+     (Start_Date    : OS_Time;
+      End_Date      : OS_Time;
       Elapsed_Leaps : out Natural;
-      Next_Leap_Sec : out Time);
-   --  Elapsed_Leaps is the sum of the leap seconds that have occured on or
+      Next_Leap_Sec : out OS_Time);
+   --  Elapsed_Leaps is the sum of the leap seconds that have occurred on or
    --  after Start_Date and before (strictly before) End_Date. Next_Leap_Sec
-   --  represents the next leap second occurence on or after End_Date. If
+   --  represents the next leap second occurrence on or after End_Date. If
    --  there are no leaps seconds after End_Date, End_Of_Time is returned.
    --  End_Of_Time can be used as End_Date to count all the leap seconds that
-   --  have occured on or after Start_Date.
+   --  have occurred on or after Start_Date.
    --
    --  Note: Any sub seconds of Start_Date and End_Date are discarded before
    --  the calculations are done. For instance: if 113 seconds is a leap
@@ -112,43 +111,73 @@ package body Ada.Calendar is
    --  Unchecked_Conversion was employed, the resulting values would be off
    --  by 100.
 
+   --------------------------
+   -- Leap seconds control --
+   --------------------------
+
+   Flag : Integer;
+   pragma Import (C, Flag, "__gl_leap_seconds_support");
+   --  This imported value is used to determine whether the compilation had
+   --  binder flag "-y" present which enables leap seconds. A value of zero
+   --  signifies no leap seconds support while a value of one enables the
+   --  support.
+
+   Leap_Support : constant Boolean := Flag = 1;
+   --  The above flag controls the usage of leap seconds in all Ada.Calendar
+   --  routines.
+
+   Leap_Seconds_Count : constant Natural := 24;
+
    ---------------------
    -- Local Constants --
    ---------------------
 
-   --  Currently none of the GNAT targets support leap seconds. At some point
-   --  it might be necessary to query a C function to determine if the target
-   --  supports leap seconds, but for now this is deemed unnecessary.
-
-   Leap_Support       : constant Boolean := False;
-   Leap_Seconds_Count : constant Natural := 23;
-
    --  The range of Ada time expressed as milis since the VMS Epoch
 
-   Ada_Low  : constant Time :=  (10 * 366 +  32 * 365 + 45) * Milis_In_Day;
-   Ada_High : constant Time := (131 * 366 + 410 * 365 + 45) * Milis_In_Day;
+   Ada_Low  : constant OS_Time :=  (10 * 366 +  32 * 365 + 45) * Milis_In_Day;
+   Ada_High : constant OS_Time := (131 * 366 + 410 * 365 + 45) * Milis_In_Day;
 
    --  Even though the upper bound of time is 2399-12-31 23:59:59.9999999
    --  UTC, it must be increased to include all leap seconds.
 
-   Ada_High_And_Leaps : constant Time :=
-                          Ada_High + Time (Leap_Seconds_Count) * Mili;
+   Ada_High_And_Leaps : constant OS_Time :=
+                          Ada_High + OS_Time (Leap_Seconds_Count) * Mili;
 
    --  Two constants used in the calculations of elapsed leap seconds.
    --  End_Of_Time is later than Ada_High in time zone -28. Start_Of_Time
    --  is earlier than Ada_Low in time zone +28.
 
-   End_Of_Time   : constant Time := Ada_High + Time (3) * Milis_In_Day;
-   Start_Of_Time : constant Time := Ada_Low  - Time (3) * Milis_In_Day;
-
-   Cumulative_Days_Before_Month :
-     constant array (Month_Number) of Natural :=
-       (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
-
-   Leap_Second_Times : array (1 .. Leap_Seconds_Count) of Time;
-   --  Each value represents a time value which is one second before a leap
-   --  second occurence. This table is populated during the elaboration of
-   --  Ada.Calendar.
+   End_Of_Time   : constant OS_Time := Ada_High + OS_Time (3) * Milis_In_Day;
+   Start_Of_Time : constant OS_Time := Ada_Low  - OS_Time (3) * Milis_In_Day;
+
+   --  The following table contains the hard time values of all existing leap
+   --  seconds. The values are produced by the utility program xleaps.adb.
+
+   Leap_Second_Times : constant array (1 .. Leap_Seconds_Count) of OS_Time :=
+     (35855136000000000,
+      36014112010000000,
+      36329472020000000,
+      36644832030000000,
+      36960192040000000,
+      37276416050000000,
+      37591776060000000,
+      37907136070000000,
+      38222496080000000,
+      38695104090000000,
+      39010464100000000,
+      39325824110000000,
+      39957408120000000,
+      40747104130000000,
+      41378688140000000,
+      41694048150000000,
+      42166656160000000,
+      42482016170000000,
+      42797376180000000,
+      43271712190000000,
+      43744320200000000,
+      44218656210000000,
+      46427904220000000,
+      47374848230000000);
 
    ---------
    -- "+" --
@@ -190,13 +219,15 @@ package body Ada.Calendar is
 
       --  The bound of type Duration expressed as time
 
-      Dur_High : constant Time := To_Relative_Time (Duration'Last);
-      Dur_Low  : constant Time := To_Relative_Time (Duration'First);
+      Dur_High : constant OS_Time :=
+                   OS_Time (To_Relative_Time (Duration'Last));
+      Dur_Low  : constant OS_Time :=
+                   OS_Time (To_Relative_Time (Duration'First));
 
-      Res_M : Time;
+      Res_M : OS_Time;
 
    begin
-      Res_M := Left - Right;
+      Res_M := OS_Time (Left) - OS_Time (Right);
 
       --  Due to the extended range of Ada time, "-" is capable of producing
       --  results which may exceed the range of Duration. In order to prevent
@@ -211,7 +242,7 @@ package body Ada.Calendar is
       --  Normal case, result fits
 
       else
-         return To_Duration (Res_M);
+         return To_Duration (Time (Res_M));
       end if;
 
    exception
@@ -225,7 +256,7 @@ package body Ada.Calendar is
 
    function "<" (Left, Right : Time) return Boolean is
    begin
-      return Long_Integer (Left) < Long_Integer (Right);
+      return OS_Time (Left) < OS_Time (Right);
    end "<";
 
    ----------
@@ -234,7 +265,7 @@ package body Ada.Calendar is
 
    function "<=" (Left, Right : Time) return Boolean is
    begin
-      return Long_Integer (Left) <= Long_Integer (Right);
+      return OS_Time (Left) <= OS_Time (Right);
    end "<=";
 
    ---------
@@ -243,7 +274,7 @@ package body Ada.Calendar is
 
    function ">" (Left, Right : Time) return Boolean is
    begin
-      return Long_Integer (Left) > Long_Integer (Right);
+      return OS_Time (Left) > OS_Time (Right);
    end ">";
 
    ----------
@@ -252,14 +283,14 @@ package body Ada.Calendar is
 
    function ">=" (Left, Right : Time) return Boolean is
    begin
-      return Long_Integer (Left) >= Long_Integer (Right);
+      return OS_Time (Left) >= OS_Time (Right);
    end ">=";
 
    ------------------------------
    -- Check_Within_Time_Bounds --
    ------------------------------
 
-   procedure Check_Within_Time_Bounds (T : Time) is
+   procedure Check_Within_Time_Bounds (T : OS_Time) is
    begin
       if Leap_Support then
          if T < Ada_Low or else T > Ada_High_And_Leaps then
@@ -278,8 +309,8 @@ package body Ada.Calendar is
 
    function Clock return Time is
       Elapsed_Leaps : Natural;
-      Next_Leap_M   : Time;
-      Res_M         : constant Time := Time (OSP.OS_Clock);
+      Next_Leap_M   : OS_Time;
+      Res_M         : constant OS_Time := OS_Clock;
 
    begin
       --  Note that on other targets a soft-link is used to get a different
@@ -306,7 +337,7 @@ package body Ada.Calendar is
          Elapsed_Leaps := 0;
       end if;
 
-      return Res_M + Time (Elapsed_Leaps) * Mili;
+      return Time (Res_M + OS_Time (Elapsed_Leaps) * Mili);
    end Clock;
 
    -----------------------------
@@ -314,22 +345,22 @@ package body Ada.Calendar is
    -----------------------------
 
    procedure Cumulative_Leap_Seconds
-     (Start_Date    : Time;
-      End_Date      : Time;
+     (Start_Date    : OS_Time;
+      End_Date      : OS_Time;
       Elapsed_Leaps : out Natural;
-      Next_Leap_Sec : out Time)
+      Next_Leap_Sec : out OS_Time)
    is
       End_Index   : Positive;
-      End_T       : Time := End_Date;
+      End_T       : OS_Time := End_Date;
       Start_Index : Positive;
-      Start_T     : Time := Start_Date;
+      Start_T     : OS_Time := Start_Date;
 
    begin
       pragma Assert (Leap_Support and then End_Date >= Start_Date);
 
       Next_Leap_Sec := End_Of_Time;
 
-      --  Make sure that the end date does not excede the upper bound
+      --  Make sure that the end date does not exceed the upper bound
       --  of Ada time.
 
       if End_Date > Ada_High then
@@ -358,7 +389,7 @@ package body Ada.Calendar is
       end if;
 
       --  Perform the calculations only if the start date is within the leap
-      --  second occurences table.
+      --  second occurrences table.
 
       if Start_T <= Leap_Second_Times (Leap_Seconds_Count) then
 
@@ -408,6 +439,7 @@ package body Ada.Calendar is
       M : Month_Number;
       D : Day_Number;
       S : Day_Duration;
+      pragma Unreferenced (Y, M, S);
    begin
       Split (Date, Y, M, D, S);
       return D;
@@ -419,12 +451,12 @@ package body Ada.Calendar is
 
    function Is_Leap (Year : Year_Number) return Boolean is
    begin
-      --  Leap centenial years
+      --  Leap centennial years
 
       if Year mod 400 = 0 then
          return True;
 
-      --  Non-leap centenial years
+      --  Non-leap centennial years
 
       elsif Year mod 100 = 0 then
          return False;
@@ -445,6 +477,7 @@ package body Ada.Calendar is
       M : Month_Number;
       D : Day_Number;
       S : Day_Duration;
+      pragma Unreferenced (Y, D, S);
    begin
       Split (Date, Y, M, D, S);
       return M;
@@ -459,6 +492,7 @@ package body Ada.Calendar is
       M : Month_Number;
       D : Day_Number;
       S : Day_Duration;
+      pragma Unreferenced (Y, M, D);
    begin
       Split (Date, Y, M, D, S);
       return S;
@@ -588,6 +622,7 @@ package body Ada.Calendar is
       M : Month_Number;
       D : Day_Number;
       S : Day_Duration;
+      pragma Unreferenced (M, D, S);
    begin
       Split (Date, Y, M, D, S);
       return Y;
@@ -608,8 +643,9 @@ package body Ada.Calendar is
 
       function Add (Date : Time; Days : Long_Integer) return Time is
          pragma Unsuppress (Overflow_Check);
+         Date_M : constant OS_Time := OS_Time (Date);
       begin
-         return Date + Time (Days) * Milis_In_Day;
+         return Time (Date_M + OS_Time (Days) * Milis_In_Day);
       exception
          when Constraint_Error =>
             raise Time_Error;
@@ -626,15 +662,13 @@ package body Ada.Calendar is
          Seconds      : out Duration;
          Leap_Seconds : out Integer)
       is
-         Mili_F : constant Duration := 10_000_000.0;
-
-         Diff_M        : Time;
-         Diff_S        : Time;
-         Earlier       : Time;
+         Diff_M        : OS_Time;
+         Diff_S        : OS_Time;
+         Earlier       : OS_Time;
          Elapsed_Leaps : Natural;
-         Later         : Time;
+         Later         : OS_Time;
          Negate        : Boolean := False;
-         Next_Leap     : Time;
+         Next_Leap     : OS_Time;
          Sub_Seconds   : Duration;
 
       begin
@@ -642,11 +676,11 @@ package body Ada.Calendar is
          --  being raised by the arithmetic operators in Ada.Calendar.
 
          if Left >= Right then
-            Later   := Left;
-            Earlier := Right;
+            Later   := OS_Time (Left);
+            Earlier := OS_Time (Right);
          else
-            Later   := Right;
-            Earlier := Left;
+            Later   := OS_Time (Right);
+            Earlier := OS_Time (Left);
             Negate  := True;
          end if;
 
@@ -666,7 +700,7 @@ package body Ada.Calendar is
             Elapsed_Leaps := 0;
          end if;
 
-         Diff_M := Later - Earlier - Time (Elapsed_Leaps) * Mili;
+         Diff_M := Later - Earlier - OS_Time (Elapsed_Leaps) * Mili;
 
          --  Sub second processing
 
@@ -697,8 +731,9 @@ package body Ada.Calendar is
 
       function Subtract (Date : Time; Days : Long_Integer) return Time is
          pragma Unsuppress (Overflow_Check);
+         Date_M : constant OS_Time := OS_Time (Date);
       begin
-         return Date - Time (Days) * Milis_In_Day;
+         return Time (Date_M - OS_Time (Days) * Milis_In_Day);
       exception
          when Constraint_Error =>
             raise Time_Error;
@@ -706,6 +741,205 @@ package body Ada.Calendar is
    end Arithmetic_Operations;
 
    ---------------------------
+   -- Conversion_Operations --
+   ---------------------------
+
+   package body Conversion_Operations is
+
+      Epoch_Offset : constant OS_Time := 35067168000000000;
+      --  The difference between 1970-1-1 UTC and 1858-11-17 UTC expressed in
+      --  100 nanoseconds.
+
+      -----------------
+      -- To_Ada_Time --
+      -----------------
+
+      function To_Ada_Time (Unix_Time : Long_Integer) return Time is
+         pragma Unsuppress (Overflow_Check);
+         Unix_Rep : constant OS_Time := OS_Time (Unix_Time) * Mili;
+      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_Shift  : constant Integer := 1900;
+         Month_Shift : constant Integer := 1;
+
+         Year   : Year_Number;
+         Month  : Month_Number;
+         Day    : Day_Number;
+         Second : Integer;
+         Leap   : Boolean;
+         Result : OS_Time;
+
+      begin
+         --  Input processing
+
+         Year  := Year_Number (Year_Shift + tm_year);
+         Month := Month_Number (Month_Shift + 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 :=
+           OS_Time
+             (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 + OS_Time (3_600) * Mili;
+         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) / Mili_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);
+
+         --  100 Nanoseconds extraction
+
+         Nano_Secs := D - Duration (tv_sec);
+         tv_nsec := Long_Integer (Nano_Secs * Mili);
+      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 occurrences
+
+         tm_sec := (if Leap_Sec then 60 else Second);
+      end To_Struct_Tm;
+
+      ------------------
+      -- To_Unix_Time --
+      ------------------
+
+      function To_Unix_Time (Ada_Time : Time) return Long_Integer is
+         pragma Unsuppress (Overflow_Check);
+         Ada_OS_Time : constant OS_Time := OS_Time (Ada_Time);
+      begin
+         return Long_Integer ((Ada_OS_Time - Epoch_Offset) / Mili);
+      exception
+         when Constraint_Error =>
+            raise Time_Error;
+      end To_Unix_Time;
+   end Conversion_Operations;
+
+   ---------------------------
    -- Formatting_Operations --
    ---------------------------
 
@@ -779,20 +1013,19 @@ package body Ada.Calendar is
 
          Ada_Min_Year : constant := 1901;
          Ada_Max_Year : constant := 2399;
-         Mili_F       : constant Duration := 10_000_000.0;
 
-         Date_M        : Time;
+         Date_M        : OS_Time;
          Elapsed_Leaps : Natural;
-         Next_Leap_M   : Time;
+         Next_Leap_M   : OS_Time;
 
       begin
-         Date_M := Date;
+         Date_M := OS_Time (Date);
 
          --  Step 1: Leap seconds processing
 
          if Leap_Support then
             Cumulative_Leap_Seconds
-              (Start_Of_Time, Date, Elapsed_Leaps, Next_Leap_M);
+              (Start_Of_Time, Date_M, Elapsed_Leaps, Next_Leap_M);
 
             Leap_Sec := Date_M >= Next_Leap_M;
 
@@ -807,12 +1040,12 @@ package body Ada.Calendar is
             Leap_Sec      := False;
          end if;
 
-         Date_M := Date_M - Time (Elapsed_Leaps) * Mili;
+         Date_M := Date_M - OS_Time (Elapsed_Leaps) * Mili;
 
          --  Step 2: Time zone processing
 
          if Time_Zone /= 0 then
-            Date_M := Date_M + Time (Time_Zone) * 60 * Mili;
+            Date_M := Date_M + OS_Time (Time_Zone) * 60 * Mili;
          end if;
 
          --  After the leap seconds and time zone have been accounted for,
@@ -834,7 +1067,7 @@ package body Ada.Calendar is
 
          --  Step 4: VMS system call
 
-         Numtim (Status, Timbuf, Date_M);
+         Numtim (Status, Timbuf, Time (Date_M));
 
          if Status mod 2 /= 1
            or else Timbuf (1) not in Ada_Min_Year .. Ada_Max_Year
@@ -870,10 +1103,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
          procedure Cvt_Vectim
            (Status         : out Unsigned_Longword;
@@ -890,8 +1123,6 @@ package body Ada.Calendar is
          Status : Unsigned_Longword;
          Timbuf : Unsigned_Word_Array (1 .. 7);
 
-         Mili_F : constant := 10_000_000.0;
-
          Y  : Year_Number  := Year;
          Mo : Month_Number := Month;
          D  : Day_Number   := Day;
@@ -902,9 +1133,10 @@ package body Ada.Calendar is
 
          Elapsed_Leaps : Natural;
          Int_Day_Secs  : Integer;
-         Next_Leap_M   : Time;
-         Res_M         : Time;
-         Rounded_Res_M : Time;
+         Next_Leap_M   : OS_Time;
+         Res           : Time;
+         Res_M         : OS_Time;
+         Rounded_Res_M : OS_Time;
 
       begin
          --  No validity checks are performed on the input values since it is
@@ -959,11 +1191,10 @@ package body Ada.Calendar is
             else
                --  Sub second extraction
 
-               if Day_Secs > 0.0 then
-                  Int_Day_Secs := Integer (Day_Secs - 0.5);
-               else
-                  Int_Day_Secs := Integer (Day_Secs);
-               end if;
+               Int_Day_Secs :=
+                 (if Day_Secs > 0.0
+                  then Integer (Day_Secs - 0.5)
+                  else Integer (Day_Secs));
 
                H  := Int_Day_Secs / 3_600;
                Mi := (Int_Day_Secs / 60) mod 60;
@@ -982,7 +1213,7 @@ package body Ada.Calendar is
          Timbuf (6) := Unsigned_Word (Se);
          Timbuf (7) := 0;
 
-         Cvt_Vectim (Status, Timbuf, Res_M);
+         Cvt_Vectim (Status, Timbuf, Res);
 
          if Status mod 2 /= 1 then
             raise Time_Error;
@@ -990,7 +1221,7 @@ package body Ada.Calendar is
 
          --  Step 3: Sub second adjustment
 
-         Res_M := Res_M + Time (Su * Mili_F);
+         Res_M := OS_Time (Res) + OS_Time (Su * Mili_F);
 
          --  Step 4: Bounds check
 
@@ -999,7 +1230,7 @@ package body Ada.Calendar is
          --  Step 5: Time zone processing
 
          if Time_Zone /= 0 then
-            Res_M := Res_M - Time (Time_Zone) * 60 * Mili;
+            Res_M := Res_M - OS_Time (Time_Zone) * 60 * Mili;
          end if;
 
          --  Step 6: Leap seconds processing
@@ -1008,7 +1239,7 @@ package body Ada.Calendar is
             Cumulative_Leap_Seconds
               (Start_Of_Time, Res_M, Elapsed_Leaps, Next_Leap_M);
 
-            Res_M := Res_M + Time (Elapsed_Leaps) * Mili;
+            Res_M := Res_M + OS_Time (Elapsed_Leaps) * Mili;
 
             --  An Ada 2005 caller requesting an explicit leap second or an
             --  Ada 95 caller accounting for an invisible leap second.
@@ -1016,7 +1247,7 @@ package body Ada.Calendar is
             if Leap_Sec
               or else Res_M >= Next_Leap_M
             then
-               Res_M := Res_M + Time (1) * Mili;
+               Res_M := Res_M + OS_Time (1) * Mili;
             end if;
 
             --  Leap second validity check
@@ -1031,7 +1262,7 @@ package body Ada.Calendar is
             end if;
          end if;
 
-         return Res_M;
+         return Time (Res_M);
       end Time_Of;
    end Formatting_Operations;
 
@@ -1062,78 +1293,4 @@ package body Ada.Calendar is
          return get_gmtoff;
       end UTC_Time_Offset;
    end Time_Zones_Operations;
-
---  Start of elaboration code for Ada.Calendar
-
-begin
-   --  Population of the leap seconds table
-
-   if Leap_Support then
-      declare
-         type Leap_Second_Date is record
-            Year  : Year_Number;
-            Month : Month_Number;
-            Day   : Day_Number;
-         end record;
-
-         Leap_Second_Dates :
-           constant array (1 .. Leap_Seconds_Count) of Leap_Second_Date :=
-             ((1972,  6, 30), (1972, 12, 31), (1973, 12, 31), (1974, 12, 31),
-              (1975, 12, 31), (1976, 12, 31), (1977, 12, 31), (1978, 12, 31),
-              (1979, 12, 31), (1981,  6, 30), (1982,  6, 30), (1983,  6, 30),
-              (1985,  6, 30), (1987, 12, 31), (1989, 12, 31), (1990, 12, 31),
-              (1992,  6, 30), (1993,  6, 30), (1994,  6, 30), (1995, 12, 31),
-              (1997,  6, 30), (1998, 12, 31), (2005, 12, 31));
-
-         Ada_Min_Year       : constant Year_Number := Year_Number'First;
-         Days_In_Four_Years : constant := 365 * 3 + 366;
-         VMS_Days           : constant := 10 * 366 + 32 * 365 + 45;
-
-         Days  : Natural;
-         Leap  : Leap_Second_Date;
-         Years : Natural;
-
-      begin
-         for Index in 1 .. Leap_Seconds_Count loop
-            Leap := Leap_Second_Dates (Index);
-
-            --  Calculate the number of days from the start of Ada time until
-            --  the current leap second occurence. Non-leap centenial years
-            --  are not accounted for in these calculations since there are
-            --  no leap seconds after 2100 yet.
-
-            Years := Leap.Year - Ada_Min_Year;
-            Days  := (Years / 4) * Days_In_Four_Years;
-            Years := Years mod 4;
-
-            if Years = 1 then
-               Days := Days + 365;
-
-            elsif Years = 2 then
-               Days := Days + 365 * 2;
-
-            elsif Years = 3 then
-               Days := Days + 365 * 3;
-            end if;
-
-            Days := Days + Cumulative_Days_Before_Month (Leap.Month);
-
-            if Is_Leap (Leap.Year)
-              and then Leap.Month > 2
-            then
-               Days := Days + 1;
-            end if;
-
-            --  Add the number of days since the start of VMS time till the
-            --  start of Ada time.
-
-            Days := Days + Leap.Day + VMS_Days;
-
-            --  Index - 1 previous leap seconds are added to Time (Index)
-
-            Leap_Second_Times (Index) :=
-              (Time (Days) * Secs_In_Day + Time (Index - 1)) * Mili;
-         end loop;
-      end;
-   end if;
 end Ada.Calendar;