KW wrote:
Hi all,
Appreciate if someone can help me out on this.
Currently, I have a tm structure holding information of the UTC time,
which is very likely to be in the past, meaning not the current time.
So, let's say I'm in CST(-6) now, and I want to know the equivalent
local time of that tm structure, how do I do that taking into
consideration daylight savings adjustments?
Well, I have gathered some info:
mktime() will convert the tm structure and return a time_t object, but
this time_t returned is of the local time, not UTC.
localtime() takes in a time_t argument(of UTC) and returns a tm
structure pointing to the local time. This is actually what I desire,
but, I still can't seem to translate the tm structure of the UTC time
to a time_t (UTC) data type.
gmtime() also takes in one argument of time_t (UTC) but returns a tm
structure pointing to the UTC time.
In short:
local tm -> mktime() -> local time_t
UTC time_t -> localtime() -> local tm
UTC time_t -> gmtime() -> UTC tm
So, what I am looking for is:
UTC tm -> ???() -> UTC time_t
As far as I know, you'll need to apply the time zone
correction manually:
time_t when;
struct tm tm = ...time in UTC...;
tm.tm_hour += -6; /* convert to local time zone */
when = mktime(&tm); /* convert local to time_t */
One way to figure the offset instead of hard-wiring "-6"
might be to pass the same arbitrary time_t value through both
gmtime() and localtime() and study the difference:
time_t when = time(NULL);
struct tm utc = *gmtime(&when);
struct tm lcl = *localtime(&when);
int delta_h = lcl.tm_hour - utc.tm_hour;
.... with some extra care around midnight, especially around
midnight on December 31! However, this isn't perfect even
with the extra care: the UTC-to-local delta in effect now
might not be the same that was in effect at the time you're
interested in, because of seasonal adjustments ("daylight
savings time"). You could, I guess, try the delta_h as
computed above, use mktime(), put the resulting time_t back
through gmtime() again, and see whether you got your original
struct tm back -- if not, you could adjust delta_h and try
again. (In fact, if you've got such a predict-and-correct
loop in place, you might as well just start delta_h at zero
and let the corrector figure it out.)
Three final points: First, some time zones' offsets from
UTC are not an integral number of hours, so you might want
to use a delta_m in addition to or instead of delta_h (I'm
not aware of any time zone that would require a delta_s).
Second, time_t is neither "local" nor "UTC" nor anything
else; such adjustments come into play only when developing
a struct tm from a time_t. Finally, I've omitted all error
checking above but you must not: all of gmtime(), localtime(),
mktime(), and even time() can fail, and not all systems "know"
their own time zone.
--
Er*********@sun.com