Calendar Types

Marcin 'Qrczak' Kowalczyk qrczak at
Mon Feb 14 16:44:39 EST 2005

Seth Kurtzberg <seth at> writes:

> So, a time zone, at least one based on geographical location, isn't
> sufficient.  Accounting for daylight savings doesn't cover every case
> either; I gave a couple of examples but doubtless there are many
> others I don't know about.

Linux (glibc) tries to provide that information. It has lots of rules
even for weird timezones.

> I think the only way to handle it is with an argument that allows
> the user to override the offset that the machine itself uses.

It's fine to be able to override, but the default should definitely be
taken from the OS.

It is possible to discover the offset which should be used for the
given timestamp, but it's clumsy: do localtime() and gmtime(), and
subtract the results:

      diff = (((loc.tm_wday - gm.tm_wday)
         * 24 + (loc.tm_hour - gm.tm_hour))
         * 60 + (loc.tm_min - gm.tm_min))
         * 60 + (loc.tm_sec - gm.tm_sec);
      if (diff < -302400) diff += 604800;
      else if (diff >= 302400) diff -= 604800;

Linux has tm_gmtoff, it can be used instead if it's available -
it's not portable.

You will not know which part of the difference is due to geographical
location and which is due to DST, but usually it doesn't matter. You
can only know whether DST is in effect or not: tm_isdst.

When converting in the other direction, from broken-down time to
timestamp, sometimes the DST is not known, yet its useful to guess it,
even though one hour in a year is ambiguous and another is impossible.
Libc can be used for that: call mktime() with tm_isdst less than 0,
and then either use tm_gmtoff or call gmtime() and subtract the results
as before.

If the year is outside the range supported by libc, I'm afraid there
is no OS-provided way to take DST into account, at least on Linux.
You can sometimes infer the geographical timezone: call tzset() and
use variable 'extern long timezone;', if it exists and has the correct
type - it's not portable. Note: it has the opposite sign to tm_gmtoff.

   __("<         Marcin Kowalczyk
   \__/       qrczak at

More information about the Libraries mailing list