
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.
--