From: "Marc A. Criley" <mcNOSPAM@mckae.com>
Subject: Dates and Times in GNAT on Linux
Date: Sun, 13 Sep 2009 10:36:58 -0500
Date: 2009-09-13T10:36:58-05:00 [thread overview]
Message-ID: <95e64$4aad119b$4a336034$30511@API-DIGITAL.COM> (raw)
I'm confused about GNAT's implementation of some aspects of date/time
processing on Linux. I'm running GNAT GPL 2009 on Ubuntu Linux; I also
live in the US Central Time Zone and Daylight Savings Time is in effect
as I write this.
This is probably a stupid misunderstanding or mistaken expectations or
feature misuse on my part, but I would really like to know what's going on.
Basically what I'm trying to do is take the time I got from from
Ada.Real.Clock and convert it to a date/time rep. The result I'm coming
up with is always an hour off. (DST effect? Read on...) Code will follow
in a bit.
I discovered that GNAT's implementation of Ada.Real_Time.Clock returns
the number of seconds since the UTC epoch start, which is very nice and
very handy. Using Real_Time.Split I can get that number of seconds into
a visible type, Seconds_Count.
I can then get the start of the Unix/UTC epoch via:
UTC_Epoch_Start := Calendar.Time_Of(1970, 1, 1)
+ Duration(Calendar.Time_Zones.UTC_Offset * 60);
-- For where I live, right now the UTC_Offset is -300 minutes,
-- i.e. -5 hours.
Adding the Real_Time seconds count (as a Duration) to UTC_Epoch_Start
gives a Calendar.Time value containing the current UTC time, from which
I can generate an image...which is an hour off from the correct value.
So I'm thinking it might be a DST problem, but shouldn't the affected
Calendar procedures be taking that into account?
I saw that the Ada.Calendar package body uses a C function,
__gnat_localtime_tzoff(), which has "Parameter 'off' captur[ing] the UTC
offset which is either retrieved from the tm struct or calculated from
the 'timezone' extern and the tm_isdst flag in the tm struct." Looking
at the code for this function it appears that _for_Linux_ the
implementation ignores the "tm_isdst" value and just uses the
"tm_gmtoff" value, while for some other Unices it does look at tm_isdst.
I'd like to think there's a good reason for doing that--including me
being an idiot--but I don't see what's going on. And unfortunately I
don't yet have a support contract with AdaCore :-)
I hacked together some C and Ada examples to illustrate this:
tmt.c:
#include <time.h>
#include <stdio.h>
void tmt_c_time(time_t rt_secs)
{
struct tm *local;
time_t t;
t = time(NULL);
printf("secs %d\n", t);
local = localtime(&t);
printf("Local time and date: %s\n", asctime(local));
local = gmtime(&t);
printf("UTC time and date: %s\n", asctime(local));
t = rt_secs;
printf("rt secs %d (from Ada)\n", t);
local = localtime(&t);
printf("Local time and date: %s\n", asctime(local));
local = gmtime(&t);
printf("UTC time and date: %s\n", asctime(local));
}
$ gcc -c -g tmt.c
tmtada.adb:
with Text_IO; use Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Calendar.Formatting; use Ada.Calendar.Formatting;
with Ada.Calendar.Time_Zones; use Ada.Calendar.Time_Zones;
procedure Tmtada is
T : Time := Clock;
Seconds : Seconds_Count;
Span : Time_Span;
Cal_Time : Ada.Calendar.Time;
UTC_Epoch : Ada.Calendar.Time;
procedure Tmt_C_Time(Rt_Secs : Seconds_Count);
pragma Import(C, Tmt_C_Time, "tmt_c_time");
use Ada.Calendar;
begin
Split(T, Seconds, Span);
Put_Line("Seconds since epoch:" & Seconds'Img);
UTC_Epoch := Ada.Calendar.Time_Of(1970, 1, 1) +
Duration(UTC_Time_Offset * 60);
Cal_Time := UTC_Epoch + Duration(Seconds);
Put_Line("Time Image " & Image(Cal_Time));
New_Line;
Put_Line("Via C...");
Tmt_C_Time(Seconds);
end Tmtada;
$ gnatmake -g tmtada -largs tmt.o
Here's what I get from a run:
[95] Marc say: ./tmtada
Seconds since epoch: 1252855814
Time Image 2009-09-13 16:30:14
Via C...
secs 1252855814
Local time and date: Sun Sep 13 10:30:14 2009
UTC time and date: Sun Sep 13 15:30:14 2009
rt secs 1252855814 (from Ada)
Local time and date: Sun Sep 13 10:30:14 2009
UTC time and date: Sun Sep 13 15:30:14 2009
Maybe my conversion from Real_Time.Time to Calendar.Time is flawed...I
don't know. Any explanation or clarifications would be much appreciated.
Marc A. Criley
Mckae Technologies
www.mckae.com
next reply other threads:[~2009-09-13 15:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-13 15:36 Marc A. Criley [this message]
2009-09-13 16:17 ` Dates and Times in GNAT on Linux Dmitry A. Kazakov
2009-09-13 19:35 ` Jeffrey R. Carter
2009-09-13 20:41 ` Marc A. Criley
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox