EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Problems within epicsTime.cpp
From: Andrew Johnson <[email protected]>
To: "Denison, PN (Peter)" <[email protected]>
Cc: [email protected]
Date: Thu, 31 Jan 2008 11:38:57 -0600
Denison, PN (Peter) wrote:

I did look at CVS HEAD and this patch before I sent my e-mail.
Unfortunately the patch won't work, ONLY IN THE UK, with the strictly
valid "Europe/London" timezone, because the DST offsets don't cancel
out. This is because on 1/1/1970, the UK was on permanent daylight
savings time, and on 1/1/1990 it was not.

I realized that in between sending my two messages... That is so annoying/unlucky/ironic, I'm temporarily speechless.

The problem is that mktime converts a local time, and we want the
distance between 2 epochs referenced from UTC.

Right, and unfortunately ISO C does not define a gm_mktime(). Unfortunately Jeff is correct that ISO C does not require that time_t has units of one second, although I suspect quite a lot of software would break on systems where a different unit is used. The description of the Posix function time() on the page linked below explicitly says "in seconds since the epoch", but also notes that this requirement is an extension to the ISO C standard:
http://www.opengroup.org/onlinepubs/009695399/functions/time.html

Ok, so maybe we should just use a constant, but we have to adjust it for scale in case time_t has different units. Here's a patch to do that, Jeff what do you think?

- Andrew
--
When a distinguished but elderly scientist states that something is
possible, he is almost certainly right.  When he states that something
is impossible, he is very probably wrong.  -- Arthur C. Clarke
Index: epicsTime.cpp
===================================================================
RCS file: /net/phoebus/epicsmgr/cvsroot/epics/base/src/libCom/osi/epicsTime.cpp,v
retrieving revision 1.25.2.18
diff -u -b -r1.25.2.18 epicsTime.cpp
--- epicsTime.cpp	13 Nov 2007 22:54:20 -0000	1.25.2.18
+++ epicsTime.cpp	31 Jan 2008 17:38:26 -0000
@@ -49,14 +49,6 @@
 static const unsigned nSecPerSec = nSecPerUSec * uSecPerSec;
 static const unsigned nSecFracDigits = 9u;
 
-static const unsigned tmEpochYear = 1900;
-static const unsigned ansiEpochYear = 1970;
-static const unsigned epicsEpochYear = 1990;
-
-static const unsigned epochMonth = 0;           // January
-static const unsigned epochDayOfTheMonth = 1;   // the 1st
-
-
 //
 // epicsTime (const unsigned long secIn, const unsigned long nSecIn)
 //
@@ -87,32 +79,8 @@
     time_t t_one  = static_cast<time_t> (1);
     this->time_tSecPerTick = difftime (t_one, t_zero);
 
-    /* We calculate the difference in seconds between the ANSI and EPICS
-     * epochs (1970-1-1, 1990-1-1).  However mktime() takes a local time
-     * and adds a timezone-specified Daylight Savings Time offset to the
-     * result it returns.  Luckily we only need the time difference in
-     * seconds between the two epochs, so the two DST corrections cancel
-     * each other out.  We offset the local time used by 12 hours so the
-     * ANSI result can never go negative whatever timezone we're in.
-     */
-
-    struct tm tmEpoch;
-    tmEpoch.tm_sec = 0;
-    tmEpoch.tm_min = 0;
-    tmEpoch.tm_hour = 12;
-    tmEpoch.tm_mday = epochDayOfTheMonth;
-    tmEpoch.tm_mon = epochMonth;
-    tmEpoch.tm_isdst = 0;
-
-    tmEpoch.tm_year = ansiEpochYear - tmEpochYear;
-    time_t ansiEpoch = mktime(&tmEpoch);
-    assert(ansiEpoch != (time_t) -1);
-
-    tmEpoch.tm_year = epicsEpochYear - tmEpochYear;
-    time_t epicsEpoch = mktime(&tmEpoch);
-    assert(epicsEpoch != (time_t) -1);
-
-    this->epicsEpochOffset = difftime (epicsEpoch, ansiEpoch);
+    /* The EPICS epoch was 631152000 seconds after the ANSI one */
+    this->epicsEpochOffset = 631152000.0 / this->time_tSecPerTick;
 
     if (this->time_tSecPerTick == 1.0 &&
         this->epicsEpochOffset <= ULONG_MAX &&

References:
RE: Problems within epicsTime.cpp Denison, PN (Peter)

Navigate by Date:
Prev: Re: Problems within epicsTime.cpp Kay-Uwe Kasemir
Next: Google Summer of Code Artem Kazakov
Index: 2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: Problems within epicsTime.cpp Denison, PN (Peter)
Next: Google Summer of Code Artem Kazakov
Index: 2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·