I'm using the standard mktime
function to turn a struct tm
into an epoch time value. The tm
fields are populated locally, and I need to get the epoch time as GMT. tm
has a gmtoff
field to allow you to set the local GMT offset in seconds for just this purpose.
But I can't figure out how to get that information. Surely there must be a standard function somewhere that will return the offset? How does localtime
do it?
The universal version of obtaining local time offset function is here.
I borrowed pieces of code from the answer in statckoverflow.
I believe the following is true in linux at least: timezone info comes from /usr/share/zoneinfo/. localtime reads /etc/localtime which should be a copy of the appropriate file from zoneinfo. You can see whats inside by doing
zdump -v
on the timezone file (zdump may be in sbin but you don't need elevated permissions to read timezone files with it). Here is a snipped of one:I guess you could parse this yourself if you want. I'm not sure if there is a stdlib function that just returns the gmtoff (there may well be but I don't know...)
edit: man tzfile describes the format of the zoneinfo file. You should be able to simply mmap into a structure of the appropriate type. It appears to be what zdump is doing based on an strace of it.
Just do the following:
Note: The seconds since epoch returned by
time()
are measured as if in Greenwich.According to
localtime
man pageSo you could either call
localtime()
and you will have the difference intimezone
or calltzset()
:Note: if you choose to go with
localtime_r()
note that it is not required to set those variables you will need to calltzset()
first to settimezone
:I guess I should have done a bit more searching before asking. It turns out there's a little known
timegm
function which does the opposite ofgmtime
. It's supported on GNU and BSD which is good enough for my purposes. A more portable solution is to temporarily set the value of theTZ
environment variable to "UTC" and then usemktime
, then setTZ
back.But
timegm
works for me.