From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Thomas Lockhart <lockhart(at)alumni(dot)caltech(dot)edu> |
Cc: | pgsql-hackers(at)postgresql(dot)org, pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: [HACKERS] Re: date conversion (was Re: Re: v7.1.1 branched and released on Tuesday ...) |
Date: | 2001-05-01 14:14:56 |
Message-ID: | 3871.988726496@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs pgsql-hackers |
I extracted from Ayal the info that he was using timezone
'Asia/Jerusalem'. That zone has the interesting property that
the DST transitions happen *at midnight*, not at a sane hour like 2AM.
I suspect that that is triggering various & sundry bugs in older
versions of mktime().
On a relatively recent Linux (LinuxPPC 2000/Q4) the worst misbehavior
I can find is
regression=# select timestamp('1993-04-02');
timestamp
------------------------
1993-04-02 01:00:00+03
(1 row)
which is about the best we can do, seeing as how midnight local time
just plain does not exist on that date in that timezone.
However on an older Linux (RedHat 5.1) I get:
regression=# select timestamp('1993-04-02');
timestamp
------------------------
2027-04-11 17:45:25+03
(1 row)
which is a tad startling. Tracing through DecodeDateTime tells the
tale:
(gdb) s
875 mktime(tm);
(gdb) p *tm
$2 = {tm_sec = 0, tm_min = 0, tm_hour = 0, tm_mday = 2, tm_mon = 3,
tm_year = 93, tm_wday = 0, tm_yday = 0, tm_isdst = -1,
tm_gmtoff = -1073745925, tm_zone = 0x81420c0 "\203\ffE\001"}
(gdb) n
876 tm->tm_year += 1900;
(gdb) p *tm
$3 = {tm_sec = 0, tm_min = 0, tm_hour = 0, tm_mday = 2, tm_mon = 3,
tm_year = 93, tm_wday = 0, tm_yday = 0, tm_isdst = -1,
tm_gmtoff = -1073745925, tm_zone = 0x81420c0 "\203\ffE\001"}
(gdb) s
877 tm->tm_mon += 1;
(gdb) s
880 *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is
Ooops.
I recommend that all uses of tm->tm_gmtoff from mktime() be guarded
along the lines of
if (tm->tm_isdst >= 0)
believe gmtoff
else
assume GMT
However, this still does not account for the reported failure of date()
since that code path doesn't use the returned value of *tzp --- and
indeed I get the right thing from select date('1993-04-02'), despite
the failure of mktime(). Probably the behavior of mktime() in this
situation varies across different glibc releases. Would some other
folk try
set timezone to 'Asia/Jerusalem';
select timestamp('1993-04-02');
select date('1993-04-02');
and report what you see?
BTW, I also see
regression=# select timestamp(date('1993-04-02'));
ERROR: Unable to convert date to tm
which is just what you'd expect if mktime() fails for this input;
I suppose there's nothing we can do about that except advise people
to update to a less broken libc...
regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | Thomas Lockhart | 2001-05-02 04:21:01 | Re: Dates and times (and timestamps) don't behave as expected |
Previous Message | Thomas Lockhart | 2001-05-01 13:32:32 | Re: Dates and times (and timestamps) don't behave as expected |
From | Date | Subject | |
---|---|---|---|
Next Message | Rod Taylor | 2001-05-01 15:07:42 | SELECT WHERE 'NOT LOCKED'? |
Previous Message | Alfred Perlstein | 2001-05-01 10:07:17 | Re: 7.1 startup recovery failure |