On Mon, 18 Jul 2005 17:34:55 +0200, Campo Weijerman <[EMAIL PROTECTED]> wrote:
> > + /* This edge case is to workaround the undefined behaviour, where the > > + * TIMEZONE makes the time go beyond the defined range. > > + * gmtime (0x7fffffff) => 2038-01-19 03:14:07 > > + * If there is a negative offset in TZ, like MET-1METDST, some broken > > + * implementations of localtime () (like AIX 5.2) barf with bogus > > + * return values: > > + * 0x7fffffff gmtime 2038-01-19 03:14:07 > > + * 0x7fffffff localtime 1901-12-13 21:45:51 > > + * 0x7fffffff mylocaltime 2038-01-19 04:14:07 > > + * 0x3c19137f gmtime 2001-12-13 20:45:51 > > + * 0x3c19137f localtime 2001-12-13 21:45:51 > > + * 0x3c19137f mylocaltime 2001-12-13 21:45:51 > > + * Given that legal timezones are typically between GMT-12 and GMT+12 > > + * we turn back the clock 23 hours before calling the localtime > > + * function, and add those to the return value. This will never cause > > + * day wrapping problems, since the edge case is Jan *19* > > + */ > > + T = *tp - 82800; /* 23 hour. allows up to GMT-23 */ > > + P = localtime (&T); > > + P->tm_hour += 23; > > + if (P->tm_hour >= 24) { > > + P->tm_hour -= 24; > > + P->tm_mday++; > > + } > > Well, it's not nice, but I suppose it should fix the boundary case. > However, I think you should also increment these other fields along > with tm_mday: > > int tm_wday; /* Day of week (Sunday = 0) */ > int tm_yday; /* Day of year (0 - 365) */ Both done now in #25173 > I'm not fond of this sort of struct tm manipulation. It's easy to > get wrong, and then you have just replaced a known bug by an unknown > one. Luckily, 2038-01-19 is supposed to be on a Tuesday, and we > are sufficiently far away from the boundaries of the week, month, and > year... Until someone starts using TZ=CUT-50, say :-( As the surrounding comments already said. By the time this workaround should be a problem, we are all on 64, 128 or even 256 bit machines As you can see, the bug is already safe for 64bit values, since the workaround only acts in a small window: + if (!tp || *tp < 0x7fff573f || *tp >= 0x80000000) + return (localtime (tp)); -- H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/) using Perl 5.6.2, 5.8.0, 5.8.5, & 5.9.2 on HP-UX 10.20, 11.00 & 11.11, AIX 4.3 & 5.2, SuSE 9.2 & 9.3, and Cygwin. http://www.cmve.net/~merijn Smoking perl: http://www.test-smoke.org, perl QA: http://qa.perl.org reports to: [EMAIL PROTECTED], perl-qa@perl.org