tzset Problem/Question

I am having a problem with setting the time correctly on my system. I have
the timezone environment variable configured as follows:

TZ=est05edt04.M4.1.0/2,M10.5.0/2

I am setting our system time based on the UTC time and milliseconds provided
by a proprietary (non-QNX) system. The following code is setting the system
time and hardware clock time.

The UTC time is stored in lhtime.tv_sec and milliseconds in lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

I thought that timezone contained the number of seconds between UTC and the
local time, but the daylight savings time does not seem to be figured in so
I get my system time set one hour earlier than the actual time. Is there
something that I don’t understand about tzset and the value placed in
timezone?

Any help is greatly appreciated.

Steve Bull

Steve Bull <steven.bull@cplc.com> wrote:

I am having a problem with setting the time correctly on my system. I have
the timezone environment variable configured as follows:

TZ=est05edt04.M4.1.0/2,M10.5.0/2

I am setting our system time based on the UTC time and milliseconds provided
by a proprietary (non-QNX) system. The following code is setting the system
time and hardware clock time.

The UTC time is stored in lhtime.tv_sec and milliseconds in lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

I thought that timezone contained the number of seconds between UTC and the
local time, but the daylight savings time does not seem to be figured in so

The timezone is described as “the number of seconds that the local time
zone is earlier than UTC” – note it says “local time zone” NOT
“local time” – this suggests that it should not include daylight
savings modifications.

You will also have to look at the daylight flag – which will be 0 or 1
depending on whether or not daylight savings is in effect.

tzset();
lhtime.tv_sec -= timezone + daylight*3600;

If you are doing this at any point other than system startup, you may
want to consider using qnx_adj_time() to resynchronise, rather than
jumping your system clock forward/backward by some amount.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:ai95nu$e1v$1@nntp.qnx.com

Steve Bull <> steven.bull@cplc.com> > wrote:
I am having a problem with setting the time correctly on my system. I
have
the timezone environment variable configured as follows:

TZ=est05edt04.M4.1.0/2,M10.5.0/2

I am setting our system time based on the UTC time and milliseconds
provided
by a proprietary (non-QNX) system. The following code is setting the
system
time and hardware clock time.

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

I thought that timezone contained the number of seconds between UTC and
the
local time, but the daylight savings time does not seem to be figured in
so

The timezone is described as “the number of seconds that the local time
zone is earlier than UTC” – note it says “local time zone” NOT
“local time” – this suggests that it should not include daylight
savings modifications.

You will also have to look at the daylight flag – which will be 0 or 1
depending on whether or not daylight savings is in effect.

tzset();
lhtime.tv_sec -= timezone + daylight*3600;

If you are doing this at any point other than system startup, you may
want to consider using qnx_adj_time() to resynchronise, rather than
jumping your system clock forward/backward by some amount.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

The Watcom Help indicates that the daylight flag is set depending on whether
or not a daylight saving abbreviation is specified in the TZ environment
variable not whether we are currently in daylight savings time. Am I reading
this incorrectly or is the help incorrect on this point?

Steve

Steve Bull <steven.bull@cplc.com> wrote:

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:ai95nu$e1v$> 1@nntp.qnx.com> …
Steve Bull <> steven.bull@cplc.com> > wrote:
I am having a problem with setting the time correctly on my system. I
have
the timezone environment variable configured as follows:

TZ=est05edt04.M4.1.0/2,M10.5.0/2

I am setting our system time based on the UTC time and milliseconds
provided
by a proprietary (non-QNX) system. The following code is setting the
system
time and hardware clock time.

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

The Watcom Help indicates that the daylight flag is set depending on whether
or not a daylight saving abbreviation is specified in the TZ environment
variable not whether we are currently in daylight savings time. Am I reading
this incorrectly or is the help incorrect on this point?

Oops… you’re right… I didn’t read closely enough. Yup, it just
indicates whether or not your locale supports daylight savings time,
but doesn’t tell you whether or not you are in daylight savings time
right now.

Hm… might be the easiest way to handle this would be:

otz = strdup( getenv(“TZ”) );
setenv(“TZ”, “UTC0”, 1);
tzset();
clock_settime(…);
setenv(“TZ”,otz, 1 );
tzset();
free(otz);

Or, if you don’t care about staying in local time for this program
anywhere else, you could just leave yourself in UTC (for this program)
all the time…

(Some of the setenv/putenv routines may leak memory… but it is a pretty
slow leak, unless you are doing the above code a lot…in which case it
might be best to stay in UTC with this particular process all the time.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

The Watcom Help indicates that the daylight flag is set depending on whether
or not a daylight saving abbreviation is specified in the TZ environment
variable not whether we are currently in daylight savings time. Am I reading
this incorrectly or is the help incorrect on this point?

Oops… you’re right… I didn’t read closely enough. Yup, it just
indicates whether or not your locale supports daylight savings time,
but doesn’t tell you whether or not you are in daylight savings time
right now.

Hm… might be the easiest way to handle this would be:

otz = strdup( getenv(“TZ”) );
setenv(“TZ”, “UTC0”, 1);
tzset();
clock_settime(…);
setenv(“TZ”,otz, 1 );
tzset();
free(otz);

Hm…on further thought…

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.

And clock_settime() expects its time to be given to it in UTC, so
you shouldn’t be doing any conversions to a UTC value before calling
clock_settime(). Now, when you call rtc, it will grab the system
time (in UTC) and convert that to day/month/year/hh/mm/ss in UTC
and push that down into the BIOS clock. Again, TZ should have no
effect on that either. (TZ will affect rtc if you use the -l option
specifying that the BIOS clock is in local time, rather than UTC.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

If I may ask, why are you attempting to make timezone adjustments if your
time source from the non-QNX system is also in UTC, as the system clock is?

In my opinion the tricky thing about daylight savings time is that while you
can always derive the correct local time from the UTC time using
localtime(), you cannot always derive the correct UTC time from the local
time UNLESS you also specify explictly to mktime() whether the local time is
in daylight or standard time i.e. you have to know in advance. Enter the
tm_isdst field of a struct tm. Most of the time during the year, mktime()
could calculate the correct offset for you since the dates/times are
unambiguous (you would set tm_isdst to -1 to do this). However, every fall
for a period of two hours, this calculation isn’t possible and you’d have to
specify tm_isdst as 0 or 1 to be assured of a correct conversion.

But again, if your time source is in UTC, it’s not clear to me what you are
trying to accomplish by your adjustment prior to calling clock_settime().

If prior to the code snippet that you posted, you are doing a mktime() call
to calculate a new time_t (seconds) value, you would have to deal with the
fact that mktime() expects a local time breakdown. You could get around that
by doing something along the lines of what David suggested (i.e. setting TZ
to UTC0 prior to calling mktime(), then restoring it prior to invoking the
rtc utility). This is simple and probably the best way since it also takes
care of the regular timezone adjustment also, in addition to any possible
daylight time adjustment.

Another way would be to tell mktime() that the values you are giving it are
not daylight times (setting tm_isdst to 0). The mktime() utility will
normalize the values you give it prior to returning a time_t. So for
instance if I told it to figure out the time_t for 02:75 in the morning
today, it would adjust that to 3:15 before completing the calculation. The
same sort of hijinx apply to the tm_isdst value in combination with the
dates and times. However, I wouldn’t put absolute faith in mktime() doing
the right thing, since I know there are some bugs in the QNX 4 mktime() when
it comes to handling a few those out-of-range conditions. You’d still need
to adjust the base timezone offset yourself prior to calling mktime(), as
well.

Hope that helps a little, or at least sparks some ideas that might allow you
to figure out what’s going on.

  • Eric

“Steve Bull” <steven.bull@cplc.com> wrote in message
news:ai903o$7ut$1@inn.qnx.com

I am having a problem with setting the time correctly on my system. I have
the timezone environment variable configured as follows:

TZ=est05edt04.M4.1.0/2,M10.5.0/2

I am setting our system time based on the UTC time and milliseconds
provided
by a proprietary (non-QNX) system. The following code is setting the
system
time and hardware clock time.

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

I thought that timezone contained the number of seconds between UTC and
the
local time, but the daylight savings time does not seem to be figured in
so
I get my system time set one hour earlier than the actual time. Is there
something that I don’t understand about tzset and the value placed in
timezone?

Any help is greatly appreciated.

Steve Bull

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:aic076$hu3$2@nntp.qnx.com

David Gibbs <> dagibbs@qnx.com> > wrote:

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.
The time is set as follows:

tzset();
lhtime.tv_sec -= timezone;
clock_settime(CLOCK_REALTIME, &lhtime);
spawnl(P_NOWAIT, “/bin/rtc”, “/bin/rtc”, “-s”, “hw”, NULL);

The Watcom Help indicates that the daylight flag is set depending on
whether
or not a daylight saving abbreviation is specified in the TZ
environment
variable not whether we are currently in daylight savings time. Am I
reading
this incorrectly or is the help incorrect on this point?

Oops… you’re right… I didn’t read closely enough. Yup, it just
indicates whether or not your locale supports daylight savings time,
but doesn’t tell you whether or not you are in daylight savings time
right now.

Hm… might be the easiest way to handle this would be:

otz = strdup( getenv(“TZ”) );
setenv(“TZ”, “UTC0”, 1);
tzset();
clock_settime(…);
setenv(“TZ”,otz, 1 );
tzset();
free(otz);

Hm…on further thought…

The UTC time is stored in lhtime.tv_sec and milliseconds in
lhtime.tv_msec.

And clock_settime() expects its time to be given to it in UTC, so
you shouldn’t be doing any conversions to a UTC value before calling
clock_settime(). Now, when you call rtc, it will grab the system
time (in UTC) and convert that to day/month/year/hh/mm/ss in UTC
and push that down into the BIOS clock. Again, TZ should have no
effect on that either. (TZ will affect rtc if you use the -l option
specifying that the BIOS clock is in local time, rather than UTC.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

My original problem ended up being a problem with the time on the
proprietary system that is providing time to my QNX box, but after reading
the response from you and Eric I not sure I understand.

I am getting the time from proprietary system that gets UTC time from a
satellite, but it is stored in seconds since 1980 instead of 1970. I read
this time and convert to UTC time for the QNX machine. My timezone is set as
TZ=est05edt04,M4.1.0/2,M10.5.0/2 on the QNX machine. If I write the time
using clock_setttime() without adjusting by the timezone value (-18000) my
local time is off by 5 hours (for instance the local time is 23:15 instead
of the actual 18:15). It appears to me that clock_settime() expects the
local time and adjusts for daylight saving time. I don’t see a way that I
could set the QNX time from this system any differently.

Thanks,

Steve

Steve Bull <steven.bull@cplc.com> wrote:

My original problem ended up being a problem with the time on the
proprietary system that is providing time to my QNX box, but after reading
the response from you and Eric I not sure I understand.

I am getting the time from proprietary system that gets UTC time from a
satellite, but it is stored in seconds since 1980 instead of 1970. I read
this time and convert to UTC time for the QNX machine. My timezone is set as
TZ=est05edt04,M4.1.0/2,M10.5.0/2 on the QNX machine. If I write the time
using clock_setttime() without adjusting by the timezone value (-18000) my
local time is off by 5 hours (for instance the local time is 23:15 instead
of the actual 18:15). It appears to me that clock_settime() expects the
local time and adjusts for daylight saving time. I don’t see a way that I
could set the QNX time from this system any differently.

clock_settime() does not expect local time.

Try the following little program:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>

int main(void)
{
struct timespec tp;

tp.tv_sec = 5246060 + 1060*60;
tp.tv_nsec = 0;
if (clock_settime( CLOCK_REALTIME, &tp ) == -1)
perror(“clock_settime”);
}

After running it, from the shell type in:
date
export TZ=UTC0
date
export TZ=EST5EDT4
date

And see what you get.

I get:

$ c_settime
$ date
Tue Jan 06 05:00:01 EST 1970
$ export TZ=UTC0
$ date
Tue Jan 06 10:00:07 UTC 1970
$ export TZ=EST5EDT4
$ date
Tue Jan 06 05:00:19 EST 1970

Pretty clearly, my time was set in UTC, despite my timezone being
set as eastern.

I don’t know what is causing the different behaviour in your application
– but possibly your time source is not in UTC, or in your conversion
from 1980 based to 1970 based number of seconds you introduce a timezone
correction by mistake.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.