mktime() failure vs 31-DEC-1969 23:59:59 GMT
Paul Eggert
eggert at twinsun.com
Mon Feb 19 23:33:56 UTC 1996
From: tomp at zk3.dec.com
Date: Mon, 19 Feb 96 11:18:47 -0500
Is it a requirement (standards, etc) that localtime() work as an inverse
of mktime().
As far as I know, neither Posix nor the C Standard requires that
mktime be the inverse of localtime; but the standards are so loose
that mere conformance to the standard allows lots of bizarre behaviors
that any reasonable person would call a bug.
For example, as far as I can tell, neither standard requires that
mktime work on times in the next millenium. The same loopholes that
allow mktime implementations to mishandle times before the Epoch, also
allow them to mishandle times after the Epoch.
When filing bug reports against standards as loose as these,
we must appeal to common sense as well as to the letter of the standards;
otherwise we'll never make any progress.
> Solaris 2.5 has other problems in this area; see Sun bug 1229958
> (``ctime, localtime functions slow and incorrect'').
Where can this be found?
At http://sunsolve1.sun.com, but that report is not publicly available
unless you have a Sun support contract. However, I sent the following
info to Sun about that bug; this might might give you a flavor of the
report. I don't think the bug is fixed in Solaris 2.5.
SunOS 4.1.4 ctime runs 6 times faster than the Solaris 2.4
version on my Sparc ELCs. Perhaps you could replace the
Solaris version of the time code with the SunOS 4.1.4 version.
This will fix the bug, and also give much better performance.
Or you could substitute the public domain time code (see
<ftp://elsie.nci.nih.gov/pub/tzcode95d.tar.gz>); it's also
much faster than the Solaris 2.4 code, and it doesn't have the
bug....
Here is another test program to illustrate the bug:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TIME_T_MIN LONG_MIN
#define TIME_T_MAX LONG_MAX
char *zones_to_try[] = {"US/Pacific", "GMT0", "Hongkong"};
time_t times_to_try[] = {
TIME_T_MIN, TIME_T_MIN + 8*60*60,
TIME_T_MIN / 2,
0,
TIME_T_MAX / 2,
TIME_T_MAX - 8*60*60, TIME_T_MAX
};
int main()
{
int i, j;
for (i = 0; i < sizeof (zones_to_try) / sizeof (*zones_to_try); i++) {
char buf[100];
sprintf (buf, "TZ=%s", zones_to_try[i]);
putenv (buf);
tzset ();
for (j = 0; j < sizeof (times_to_try) / sizeof (*times_to_try); j++) {
printf ("%8lx\t%.24s\t%s\n",
times_to_try[j],
ctime (×_to_try[j]),
zones_to_try[i]);
}
}
return 0;
}
Under Solaris 2.4 this program outputs the following lines.
The lines marked `*' are incorrect.
80000000 Mon Jan 18 20:14:08 2038 US/Pacific *
80007080 Fri Dec 13 21:45:52 1901 US/Pacific *
c0000000 Mon Dec 23 02:22:56 1935 US/Pacific
0 Wed Dec 31 16:00:00 1969 US/Pacific
3fffffff Sat Jan 10 05:37:03 2004 US/Pacific
7fff8f7f Mon Jan 18 11:14:07 2038 US/Pacific
7fffffff Mon Jan 18 19:14:07 2038 US/Pacific
80000000 Fri Dec 13 20:45:52 1901 GMT0
80007080 Sat Dec 14 04:45:52 1901 GMT0
c0000000 Mon Dec 23 10:22:56 1935 GMT0
0 Thu Jan 1 00:00:00 1970 GMT0
3fffffff Sat Jan 10 13:37:03 2004 GMT0
7fff8f7f Mon Jan 18 19:14:07 2038 GMT0
7fffffff Tue Jan 19 03:14:07 2038 GMT0
80000000 Sat Dec 14 04:22:28 1901 Hongkong *
80007080 Sat Dec 14 12:22:28 1901 Hongkong *
c0000000 Mon Dec 23 18:22:56 1935 Hongkong
0 Thu Jan 1 08:00:00 1970 Hongkong
3fffffff Sat Jan 10 21:37:03 2004 Hongkong
7fff8f7f Tue Jan 19 03:14:07 2038 Hongkong
7fffffff Sat Dec 14 04:45:51 1901 Hongkong *
The starred lines should read as follows, respectively:
80000000 Fri Dec 13 12:45:52 1901 US/Pacific
80007080 Fri Dec 13 20:45:52 1901 US/Pacific
80000000 Sat Dec 14 04:45:52 1901 Hongkong
80007080 Sat Dec 14 12:45:52 1901 Hongkong
7fffffff Tue Jan 19 11:14:07 2038 Hongkong
More information about the tz
mailing list