EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: EPICS_TIMEZONE, TIMEZONE, vxWorks daylight saving
From: Kay-Uwe Kasemir <[email protected]>
To: tech talk <[email protected]>
Date: Tue, 20 Mar 2007 10:32:26 -0400
Hi:

Andrew recently sent good instructions on setting
EPICS_TIMEZONE=CUS::360:040402:103102
or EPICS_TIMEZONE=EUS::300:040402:103102
or ... depending on where you are around to world
to instruct vxWorks about the current daylight saving time rules,
which changed this year for the US.

At runtime, however, vxWorks only cares about TIMEZONE=...
So on a running IOC, you use
putenv("TIMEZONE=EUS::300:040402:103102")
and all is fine. No reboot.

So we figured that we add this putenv("TIMEZONE=...)
to our startup files, in order to get the time
right when an IOC needs a reboot.

Very bad idea.

If you want to add this putenv call to your
startup files, _you_must_use_ EPICS_TIMEZONE.
Set EPICS_TIMEZONE, either via putenv() in your
startup file or by compiling EPICS base with
a properly configured CONFIG_SITE_ENV.
Don't set TIMEZONE.

In case you have other code besides EPICS on the
CPU that needs a correct TIMEZONE,
load EPICS first, which will set TIMEZONE from
EPICS_TIMEZONE.


Detailed Reason: When the EPICS IOC core code is loaded -- loaded! this is before iocInit() is invoked! -- the following C++ initialization code runs from libCom/osi/epicsTime.cpp:

epicsTimeLoadTimeInit::epicsTimeLoadTimeInit ()
{
    static const time_t ansiEpoch = 0;
    double secWest;
    {
        time_t current = time ( NULL );
        time_t error;
        struct tm date;
        int status = epicsTime_gmtime ( &current, &date );
        assert ( status == epicsTimeOK );
        error = mktime ( &date );
        assert ( error != (time_t) - 1 );
        secWest =  difftime ( error, current );
    }

On Unix, and maybe RTEMS, all is fine.
But on vxWorks, two things happen:
1) epicsTime_gmtime(), calling vxWorks' gmtime_r(),
does not initialize date.tm_isdst.
It's left with whatever was on the stack for 'date'.
Possibly bad.
In any case, mktime converts the date with the TIMEZONE settings,
so secWest includes the DST offset if you had TIMEZONE set
before loading this code.
2) Later on, the code assumes that "secWest does not include a DST offset",
and computes an epoch offset for 1970..1990 that's 1 hour off.


In some cases you might not notice any problem because the 1 hour off
cancels out. We had major problems because our IOCs run code that
compares the timestamps received via NFS, the SNS timing system,
and the local IOC clock, and alarms if they don't match within
a certain limit. 1 hour off was too much.

Thanks to Dave Thompson, Andrew Johnson, Jeff Hill for figuring this out.
Navigate by Date:
Prev: Re: Timed Execution Kay-Uwe Kasemir
Next: ChannelArchiver archiveviewer David Dudley
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: .cmd file downloading problem Êêñot;
Next: ChannelArchiver archiveviewer David Dudley
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 10 Nov 2011 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·