Getting time zone information? 
Author Message
 Getting time zone information?

Is there a reasonably clean and portable way in standard C to
determine the current time zone as an offset from UTC (GMT)?  The
<time.h> header provides both localtime() and gmtime() functions, so
it obviously expects the implementation to have this information, but
there doesn't seem to be any good way to get at it.

What I really need is something like mktime(), but defined in terms of
UTC rather than local time.  If I knew the time zone, I could simply
call mktime() and adjust the result (I'm willing to assume that time_t
is an integer type with 1-second resolution).

I've thought of calling gmtime() and localtime() with the same time_t
value and comparing the results, but that's too ugly (though I may end
up doing it anyway).

If I have to, I can probably get away with assuming Unix and/or POSIX.

I know that the proposed mkxtime() function in C9X will do what I
want, but of course it's not available.

aTdHvAaNnKcSe

--

San Diego Supercomputer Center  < http://www.*-*-*.com/ >                 <*>
Techno-geek.  Mouse bigger than phone.  Bites heads off virtual chickens.
--



Sat, 29 Sep 2001 03:00:00 GMT  
 Getting time zone information?
In C, there is one sure-fire way to get this information. Ask the user what
time zone (s)he is in.

--

Paul Lutus
www.arachnoid.com

Quote:

>Is there a reasonably clean and portable way in standard C to
>determine the current time zone as an offset from UTC (GMT)?  The
><time.h> header provides both localtime() and gmtime() functions, so
>it obviously expects the implementation to have this information, but
>there doesn't seem to be any good way to get at it.

>What I really need is something like mktime(), but defined in terms of
>UTC rather than local time.  If I knew the time zone, I could simply
>call mktime() and adjust the result (I'm willing to assume that time_t
>is an integer type with 1-second resolution).

>I've thought of calling gmtime() and localtime() with the same time_t
>value and comparing the results, but that's too ugly (though I may end
>up doing it anyway).

>If I have to, I can probably get away with assuming Unix and/or POSIX.

>I know that the proposed mkxtime() function in C9X will do what I
>want, but of course it's not available.

>aTdHvAaNnKcSe

>--

>San Diego Supercomputer Center  <http://www.sdsc.edu>                 <*>
>Techno-geek.  Mouse bigger than phone.  Bites heads off virtual chickens.
>--


--



Mon, 01 Oct 2001 03:00:00 GMT  
 Getting time zone information?

Quote:
>Is there a reasonably clean and portable way in standard C to
>determine the current time zone as an offset from UTC (GMT)?  The
><time.h> header provides both localtime() and gmtime() functions, so
>it obviously expects the implementation to have this information, but
>there doesn't seem to be any good way to get at it.

local_tm = localtime(time)
gmt_tm = gmtime(time)

if (!tm_sanity_check(local_tm, gmt_tm)) {
        exit(EXIT_FAILURE);

Quote:
}

offset = local_tm->tm_hour - gmt_tm->tm_hour;

int tm_sanity_check(local_tm, gmt_tm) {
        does local_tm->tm_mday == gmt_tm->tm_mday;
        ....

Quote:
}

I presume you're looking for the offset in hours from GMT
of the current value of your timezone.

I'm curious. What happens in Europe? Is it GMT+23 or GMT-1?
GMT+23 would make sense but that doesn't prove anything. And
what about the dateline? Hmm, curious. I'll have to get a good
book on timekeeping. In retrospect my method might not
be so complete given the dateline and daylight savings. My
program might do the equivalent of a jet flipping over as it
crosses the equator, well dateline or dst in my case.

-Matthew
--



Mon, 01 Oct 2001 03:00:00 GMT  
 Getting time zone information?
[This followup was also e-mailed to the cited author.]


wrote in comp.lang.c.moderated:

Quote:
>Is there a reasonably clean and portable way in standard C to
>determine the current time zone as an offset from UTC (GMT)?

>I've thought of calling gmtime() and localtime() with the same time_t
>value and comparing the results, but that's too ugly (though I may end
>up doing it anyway).

I think you're on to something there. localtime() and gmtime() both give
you broken-down times, which will be different unless your time zone is
currently on UT.

If you then mktime() the result of gmtime(), mktime() assumes that its
argument is local time. So if your time zone is UT-0500, and it is
currently 3:00 am in your location, gmtime() will put 8:00 am in the
struct and when you mktime() it the result will be 5 hours ahead.

Don't assume that time_t values are in seconds; do it right and pass them
to difftime() to get the difference in seconds. That should be divisible
by 30*60, but there are some time zones that are off by 30 minutes plus
some number of hours from UT (Newfoundland, for instance).

The following code ought to work (but see below). I compiled it on MSVC
1.52, but the functions are all from the standard so every compiler
should have them. (However, the standard points out that not every C
implementation is required to handle time zones, or daylight savings
time. You have been warned!)

#include <stdio.h>
#include <time.h>

double zone(void) {
        /* returns the number of hours difference between local
        time and UT, positive for east and negative for west

        strategy: Capture local time, but then trick mktime() into
        interpreting it as UT. The difference between that result and
        actual local time is the time-zone difference. */

        time_t local_cal = time(NULL);
        struct tm gm_brokendown = *gmtime(&local_cal);
        time_t ut_cal = mktime(&gm_brokendown);

        return difftime(local_cal, ut_cal) / 3600.0;

Quote:
}

int main() {
    printf("%lf\n", zone());

    return 0;

Quote:
}

The actual result printed is -5.0000, not -4.0000 as I would expect since
I'm in Eastern Daylight Time in the US.

I found that the Microsoft library is not setting the tm_isdst value, so
that's probably why the value is wrong. If I set it explicitly to 1, I do
obtain the correct value. I don't know whether the discrepancy is due to
my not having TZ correctly set (I've got TZ=EST5EDT, which seems to be
what the Microsoft library wants), or a Microsoft bug, or some other
factor. (I also tried calling Microsoft's _tzset() function, but it made
no difference.)

--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
                                    http://www.mindspring.com/~brahms/
My reply address is correct as is. The courtesy of providing a correct
reply address is more important to me than time spent deleting spam.
--



Mon, 01 Oct 2001 03:00:00 GMT  
 Getting time zone information?
I could be wrong, but I believe the "magic" is the setting of the
TZ environment variable. gmtime() gives back the current clock
value whereas localtime() consults the TZ environment variable
to get the offset.

Quote:

>Is there a reasonably clean and portable way in standard C to
>determine the current time zone as an offset from UTC (GMT)?  The
><time.h> header provides both localtime() and gmtime() functions, so
>it obviously expects the implementation to have this information, but
>there doesn't seem to be any good way to get at it.

>What I really need is something like mktime(), but defined in terms of
>UTC rather than local time.  If I knew the time zone, I could simply
>call mktime() and adjust the result (I'm willing to assume that time_t
>is an integer type with 1-second resolution).

>I've thought of calling gmtime() and localtime() with the same time_t
>value and comparing the results, but that's too ugly (though I may end
>up doing it anyway).

>If I have to, I can probably get away with assuming Unix and/or POSIX.

>I know that the proposed mkxtime() function in C9X will do what I
>want, but of course it's not available.

>aTdHvAaNnKcSe

>--

>San Diego Supercomputer Center  <http://www.sdsc.edu>                 <*>
>Techno-geek.  Mouse bigger than phone.  Bites heads off virtual chickens.
>--


--



Mon, 01 Oct 2001 03:00:00 GMT  
 Getting time zone information?

Quote:

> Is there a reasonably clean and portable way in standard C to
> determine the current time zone as an offset from UTC (GMT)?  The
> <time.h> header provides both localtime() and gmtime() functions, so
> it obviously expects the implementation to have this information, but
> there doesn't seem to be any good way to get at it.

No.  And note that localtime and gmtime are both permitted to fail if
the implementation is unable to convert the specified time, so it would
be more accurate to say that it hopes timezone information will be
available but recognizes that it may well not be.  There were a set of
extended time functions in the initial drafts of C9X (mkxtime, zonetime,
and strfxtime) that would have allowed you to intuit the information a
bit more easily, but the committee was persuaded that they didn't go
far enough toward solving the various problems with the existing time
functions to be worth adding and they have since been removed.

There are people working on improved library routines for handling
times, hopefully their work will be included in some future amendment
or version of the standard.

-Larry Jones

Don't you hate it when your boogers freeze? -- Calvin
--



Mon, 01 Oct 2001 03:00:00 GMT  
 Getting time zone information?


Stan> Don't assume that time_t values are in seconds; do it right and
Stan> pass them to difftime() to get the difference in seconds. That
Stan> should be divisible by 30*60, but there are some time zones
Stan> that are off by 30 minutes plus some number of hours from UT
Stan> (Newfoundland, for instance).

There are also one or two quarter-hour zones; Nepal (+0545) is the
one that springs to mind.  I think the difference should be an exact
number of minutes, but beyond that either work in hours and minutes
or in minutes alone.
--



Fri, 05 Oct 2001 03:00:00 GMT  
 Getting time zone information?

Quote:

> The actual result printed is -5.0000, not -4.0000 as I would expect since
> I'm in Eastern Daylight Time in the US.

> I found that the Microsoft library is not setting the tm_isdst value, so
> that's probably why the value is wrong. If I set it explicitly to 1, I do
> obtain the correct value. I don't know whether the discrepancy is due to
> my not having TZ correctly set (I've got TZ=EST5EDT, which seems to be
> what the Microsoft library wants), or a Microsoft bug, or some other
> factor. (I also tried calling Microsoft's _tzset() function, but it made
> no difference.)

gmtime sets tm_isdst to 0 because UTC doesn't have Daylight Saving
Time.  Try explicitly setting it to -1 before you call mktime to force
mktime to guess.  (This will, of course, lead to interesting results
if the time in question is during the changeover, but should work
correctly otherwise.)

-Larry Jones

You just can't ever be too careful. -- Calvin
--



Fri, 05 Oct 2001 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Real time From Time Zone information

2. How to convert local time with specific time zone to UTC time in Win32 API

3. How to convert local time to gmt using a local variable time zone per process/thread

4. set date/time/time zone dialog

5. Obtain Time Zone

6. Time Zones

7. How to maintain TimeStamp consistency across Time Zones?

8. Dataset DateTime column value affected by time zone setting

9. Need time zone conversion routine/program/function that is callable, pcumming

10. localtime() / time zone question

11. About time zone in c

12. Time zone

 

 
Powered by phpBB® Forum Software