BUG: Solaris mktime with multiple timezones

Scott Harrington seh4 at ix.netcom.com
Fri Nov 6 18:16:10 UTC 1998


I have posted the attached message to comp.unix.solaris, so replies
should probably be posted there.  I wanted to notify this mailing list
since the bug affects those who use multiple time zones in their
programs.

-------- Original Message --------
Subject: BUG: Solaris mktime with multiple timezones
Date: Fri, 06 Nov 1998 18:09:17 +0000
From: Scott Harrington <seh4 at ix.netcom.com>
Newsgroups: comp.unix.solaris

I have uncovered a bug in the mktime() routine found in libc.so.1 and
libc.a on my SunOS 5.5.1 Generic_103640-12 sun4u sparc SUNW,Ultra-2
machine:

-rw-r--r--   1 bin      bin      1155756 Jun 23  1997 /usr/lib/libc.a
-rwxr-xr-x   1 bin      bin       664760 Jun 23  1997 /usr/lib/libc.so.1

The error is that mktime() returns WRONG values when you're switching
between multiple time zones in a single program.

I have attached a small program which should determine if your system
has the bug or not.  I make a mktime call in GB timezone, and then in
GMT timezone. The second lookup returns incorrect values.  If you have
the bug, your output will be:

TZ=GB 892162800 0 0 0 10 3 98 5 99 1 should be
TZ=GB 892162800 0 0 0 10 3 98 5 99 1

TZ=GMT 892162800 0 0 23 9 3 98 4 98 0 should be
TZ=GMT 892166400 0 0 0 10 3 98 5 99 0

On systems which implement mktime correctly, the output will be:

TZ=GB 892162800 0 0 0 10 3 98 5 99 1 should be
TZ=GB 892162800 0 0 0 10 3 98 5 99 1

TZ=GMT 892166400 0 0 0 10 3 98 5 99 0 should be
TZ=GMT 892166400 0 0 0 10 3 98 5 99 0

I am curious to find out on which systems this bug exists. (2.6? 
/opt/SUNWspro/lib/libc.so.1?)  The public Sunsolve patch list apropos
'libc' only led me to patch 103612-46 (I already had 103612-30) and
applying this patch did not fix the problem.

I have a crude LD_PRELOAD workaround (using the implementation of mktime
from GNU glibc-2.0.7) for existing executables, if anyone is interested
let me know and I will mail it or post it to this newsgroup.
-------------- next part --------------
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  time_t t;

  {
    struct tm tmBuf = {0, 0, 0, 10, 3, 98, 0, 0, -1};
    putenv("TZ=GB");
    t = mktime(&tmBuf);
    printf("TZ=GB %ld %d %d %d %d %d %d %d %d %d", t,
           tmBuf.tm_sec, tmBuf.tm_min, tmBuf.tm_hour,
           tmBuf.tm_mday, tmBuf.tm_mon, tmBuf.tm_year,
           tmBuf.tm_wday, tmBuf.tm_yday, tmBuf.tm_isdst);
    printf(" should be\n");
    printf("TZ=GB 892162800 0 0 0 10 3 98 5 99 1\n");
  }

  printf("\n");

  {
    struct tm tmBuf = {0, 0, 0, 10, 3, 98, 0, 0, -1};
    putenv("TZ=GMT");
    t = mktime(&tmBuf);
    printf("TZ=GMT %ld %d %d %d %d %d %d %d %d %d", t,
           tmBuf.tm_sec, tmBuf.tm_min, tmBuf.tm_hour,
           tmBuf.tm_mday, tmBuf.tm_mon, tmBuf.tm_year,
           tmBuf.tm_wday, tmBuf.tm_yday, tmBuf.tm_isdst);
    printf(" should be\n");
    printf("TZ=GMT 892166400 0 0 0 10 3 98 5 99 0\n");
  }

  exit(0);
}




More information about the tz mailing list