G
Greg Martin
The following is applicable to POSIX systems, where a time_t value
represents seconds since the epoch. C makes no such guarantee.
A time_t value *always* represents seconds since the "epoch', which is
defined as 1970-01-01 00:00:00 UTC. It never refers to local time.
(Well, it can refer to anything you like, but C or POSIX standard
functions that deal with time_t values treat them as seconds since the
epoch, as defined above.) (I'm ignoring leap seconds.)
In your program, you compute a struct tm value by calling localtime()
with a time_t value returned by time(). That struct tm value refers to
the local time, not UTC.
For example, as I'm typing this, my local time is:
Thu 2013-02-07 11:35:50 PST
which results in a struct tm value of (omitting some members)
(struct tm){ .tm_year = 113,
.tm_mon = 1,
.tm_mday = 7,
.tm_hour = 11,
.tm_min = 35,
.tm_sec = 50 }
You then pass (a pointer to) that struct tm into your tz_mktime()
function, which sets the time zone to UTC (by setting the
TZ environment variable to the empty string -- that's also
POSIX-specific) and then uses mktime() to convert the struct tm
value to a time_t value.
mktime() treats the above struct tm value as 2013-02-07 11:35:50 *in
local time*. Since you've set the timezone to UTC, local time is UTC.
So the result is 1360236950, the time_t representation for 2013-02-07
11:35:50 UTC -- off by 8 hours from 2013-02-07 11:35:50 PST.
I don't think I was very clear. It seems to me mktime shouldn't behave
this way. It would seem more useful to have mktime return a value in
UTC, not adjusted to the TZ field and to do that struct tm would need to
"know" what TZ it refers to. I suppose I'm presuming that somone doesn't
want to normalize to local time but until I'm viewing the time I don't
see and advantage to the conversion.
I don't know if it's an oversight. <time.h> generally has poor
support for time zones.
There have been attempts to improve this (see, for example,
<http://www.cl.cam.ac.uk/~mgk25/time/c/>), but they've never actually
been incorporated into the standard.
Perhaps it's this poor support for time zones that's at issue but in a
globally networked environment it would make sense to me to stay in UTC
until a change is explicitly requested.