Epoch in Ada

Here’s the translated code and explanation in Ada, formatted in Markdown suitable for Hugo:

A common requirement in programs is getting the number of seconds, milliseconds, or nanoseconds since the Unix epoch. Here’s how to do it in Ada.

with Ada.Text_IO;
with Ada.Calendar;
with Ada.Calendar.Formatting;
with Ada.Calendar.Time_Zones;

procedure Epoch is
   use Ada.Text_IO;
   use Ada.Calendar;
   use Ada.Calendar.Formatting;
   use Ada.Calendar.Time_Zones;

   Now : Time := Clock;
   Seconds_Since_Epoch : Integer;
   Milliseconds_Since_Epoch : Long_Integer;
   Nanoseconds_Since_Epoch : Long_Long_Integer;
begin
   Put_Line (Image (Now));

   -- Get seconds since Unix epoch
   Seconds_Since_Epoch := Integer (Seconds (Now) - Seconds (Time_Of (1970, 1, 1, 0.0)));
   Put_Line (Seconds_Since_Epoch'Image);

   -- Get milliseconds since Unix epoch
   Milliseconds_Since_Epoch := Long_Integer (Seconds_Since_Epoch) * 1000 +
                               Long_Integer (Sub_Second (Now) * 1000);
   Put_Line (Milliseconds_Since_Epoch'Image);

   -- Get nanoseconds since Unix epoch
   Nanoseconds_Since_Epoch := Long_Long_Integer (Seconds_Since_Epoch) * 1_000_000_000 +
                              Long_Long_Integer (Sub_Second (Now) * 1_000_000_000);
   Put_Line (Nanoseconds_Since_Epoch'Image);

   -- Convert seconds since epoch back to Time
   declare
      Epoch_Time : Time := Time_Of (1970, 1, 1, 0.0);
      Converted_Time : Time := Epoch_Time + Duration (Seconds_Since_Epoch);
   begin
      Put_Line (Image (Converted_Time));
   end;

   -- Convert nanoseconds since epoch back to Time
   declare
      Epoch_Time : Time := Time_Of (1970, 1, 1, 0.0);
      Converted_Time : Time := Epoch_Time + Duration (Float (Nanoseconds_Since_Epoch) / 1_000_000_000.0);
   begin
      Put_Line (Image (Converted_Time));
   end;
end Epoch;

In this Ada program, we use the Ada.Calendar package to work with time. The Clock function gives us the current time.

To get the seconds, milliseconds, and nanoseconds since the Unix epoch, we calculate the difference between the current time and the Unix epoch (January 1, 1970). We use the Seconds function to get the integral part of the seconds, and Sub_Second to get the fractional part.

We can also convert integer seconds or nanoseconds since the epoch back into the corresponding Time value by adding the duration to the epoch time.

To compile and run this Ada program:

$ gnatmake epoch.adb
$ ./epoch
2023-06-19 10:15:30.50
1687169730
1687169730500
1687169730500000000
2023-06-19 10:15:30.00
2023-06-19 10:15:30.50

Note that the exact output will depend on when you run the program.

Next, we’ll look at another time-related task: time parsing and formatting.