From: tomp@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