Re: Bug #630: date/time storage problem: timestamp parsed

From: Sean Chittenden <sean(at)chittenden(dot)org>
To: Thomas Lockhart <lockhart(at)fourpalms(dot)org>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: Bug #630: date/time storage problem: timestamp parsed
Date: 2002-04-10 04:44:42
Message-ID: 20020409214442.T66679@ninja1.internal
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2002-04-10 05:01:42 Re: Bug #630: date/time storage problem: timestamp parsed
Previous Message Tom Lane 2002-04-10 04:26:43 Re: Bug #630: date/time storage problem: timestamp parsed