Re: Bug #630: date/time storage problem: timestamp parsed - Mailing list pgsql-bugs
From | Sean Chittenden |
---|---|
Subject | Re: Bug #630: date/time storage problem: timestamp parsed |
Date | |
Msg-id | 20020409214442.T66679@ninja1.internal Whole thread Raw |
In response to | Re: Bug #630: date/time storage problem: timestamp parsed (Thomas Lockhart <lockhart@fourpalms.org>) |
Responses |
Re: Bug #630: date/time storage problem: timestamp parsed
|
List | pgsql-bugs |
> > Looks like it's a "bug" in mktime() on FreeBSD: it doesn't seem to > > do so well with invalid times that happen between daylight savings > > time... or is that a postgres thing for not kicking up an error > > (out of bounds time)? Or should 2am PST be converted to 3am? -sc > > Here is the man page on Linux: > > The mktime() function converts a broken-down time structure, > expressed as local time, to calendar time representation. The > function ignores the specified contents of the structure members > tm_wday and tm_yday and recomputes them from the other information > in the broken-down time structure. If structure members are outside > their legal interval, they will be normalized (so that, e.g., 40 > October is changed into 9 November). Calling mktime() also sets the > external variable tzname with information about the current time > zone. If the specified broken-down time cannot be represented as > calendar time (seconds since the epoch), mktime() returns a value of > (time_t)(-1) and does not alter the tm_wday and tm_yday members of > the broken-down time structure. > > > Does that look similar to FreeBSD? Very familiar, from mktime(2): The functions mktime() and timegm() convert the broken-down time in the structure pointed to by tm into a time value with the same encoding as that of the values returned by the time(3) function (that is, seconds from the Epoch, UTC). mktime() interprets the input structure according to the current timezone setting (see tzset(3)). timegm() interprets the input structure as representing Universal Coordinated Time (UTC). The original values of the tm_wday and tm_yday components of the struc- ture are ignored, and the original values of the other components are not restricted to their normal ranges, and will be normalized if needed. For example, October 40 is changed into November 9, a tm_hour of -1 means 1 hour before midnight, tm_mday of 0 means the day preceding the current month, and tm_mon of -2 means 2 months before January of tm_year. (A positive or zero value for tm_isdst causes mktime() to presume initially that summer time (for example, Daylight Saving Time) is or is not in effect for the specified time, respectively. A negative value for tm_isdst causes the mktime() function to attempt to divine whether summer time is in effect for the specified time. The tm_isdst and tm_gmtoff members are forced to zero by timegm().) > I don't think that our code checks explicitly for a "-1" return, > since the range is checked just before the call, but it would > probably be a good idea if it did (assuming that other mktime() > implementations had the same convention for an error return of > course). Just poked through how Ruby handles this and it looks like they go to reasonable lengths to make sure that it "does the right thing." http://www.ruby-lang.org/~knu/cgi-bin/cvsweb.cgi/ruby/time.c?rev=1.55&content-type=text/x-cvsweb-markup irb(main):005:0> Time.local(2002,4,7,1) Sun Apr 07 01:00:00 PST 2002 irb(main):006:0> Time.local(2002,4,7,3) Sun Apr 07 03:00:00 PDT 2002 irb(main):007:0> Time.local(2002,4,7,2) Sun Apr 07 03:00:00 PDT 2002 irb(main):008:0> Time.local(2002,4,7,2,20) Sun Apr 07 03:20:00 PDT 2002 It's artistically licensed... ::shrug:: Time.local is a thin wrapper around mktime(). Check out make_time_t() in the link above. > This is the first report I can remember in 6 years of this > particular symptom, and I have the strong feeling that no matter > what we end up doing there *is* a problem with the FreeBSD database > of time zones or (possibly) in its implementation of mktime(). I hope so... this bug hit me nasty like. I was doing a time series regression and thought it'd be a cute exercise to sum up the components... when I hit only ~99.7% and found out that part of my data was in 2036 I... flipped, freaked out, debugged, cursed, scratched head, cursed more... then I went for a Guinness and my world was calm again. :~) > What do you see as the return value from mktime()? Ehh... let me hack/check. Looks like 11. ?? In lib/libc/stdtime/localtime.c, WRONG is defined as -1, not 11. 1490 t = mktime(tmp); (gdb) 1491 fprintf(stderr, "%p\n", t); /* GCC optimizes this away if I don't do something */ (gdb) 0x3c5e5ba0 (gdb) print t $1 = 11 Doesn't make much sense to me where that'd come from... ? -sc -- Sean Chittenden
pgsql-bugs by date: