Date/time on glibc2 linux - Mailing list pgsql-hackers
| From | Oleg Broytmann |
|---|---|
| Subject | Date/time on glibc2 linux |
| Date | |
| Msg-id | Pine.SOL2.3.96.SK.981203213845.18181A-100000@sun.med.ru Whole thread Raw |
| Responses |
Re: [HACKERS] Date/time on glibc2 linux
|
| List | pgsql-hackers |
Hello!
The following gave me wrong result:
xxx=> select datetime(current_date, '11:00');
datetime
----------------------------
Thu 03 Dec 17:00:00 1998 MSK
(1 row)
and I started investigation. Soon I found I only have the problem on
glibc2-based linuxes (RedHat 5.1 and Debian 2.0), RedHat 4.2 and Solaris
are Ok. Well, it looked like an error in glibc2, and I continued. I wrote the
program:
-----
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv) { char strf_buf[100]; time_t today_t; struct tm * today;
memset(strf_buf, 0, 99); today_t = time(NULL); today = localtime(&today_t); strftime(strf_buf, 100, "%Z", today);
printf("%s\n",strf_buf);
/* In Moscow I expect MSK/MSD/1/10800 */ printf("%s\n%s\n%d\n%ld\n", tzname[0], tzname[1], daylight, timezone);
return 0;
}
-----
I expected to have results:
-----
MSK
MSK
MSD
1
-10800
-----
Ok, I've got it as expected on RH4.2 and Solaris. RH5.1 and Debian2.0
gave wrong results (although 1st line was Ok: MSK - produced by strftime).
Continued, I found to my big surprize that Python programs do date/time
arithmetic right an all platforms. I looked into python's timemodule.c and
found some code with ifdef's. When I looked into config.h, I found that on
"good" platforms there is HAVE_TZNAME defined, but on "bad" platforms it is
undefined. Because of this definition "bad" platforms execute the following
code:
#else /* !HAVE_TZNAME */
#if HAVE_TM_ZONE {
#define YEAR ((time_t)((365 * 24 + 6) * 3600)) time_t t; struct tm *p; long winterzone, summerzone;
charwintername[10], summername[10]; /* XXX This won't work on the southern hemisphere. XXX Anybody got a
betteridea? */ t = (time((time_t *)0) / YEAR) * YEAR; p = localtime(&t); winterzone = -p->tm_gmtoff;
strncpy(wintername,p->tm_zone ? p->tm_zone : " ", 9); wintername[9] = '\0'; t += YEAR/2; p =
localtime(&t); summerzone = -p->tm_gmtoff; strncpy(summername, p->tm_zone ? p->tm_zone : " ", 9);
summername[9]= '\0'; ins(d, "timezone", PyInt_FromLong(winterzone)); ins(d, "altzone",
PyInt_FromLong(summerzone)); ins(d, "daylight", PyInt_FromLong((long)(winterzone != summerzone)));
ins(d, "tzname", Py_BuildValue("(zz)", wintername, summername)); }
#else
WOW!!! Look, look here - how tzname and timezone calculated! (Actually,
recalculated - glibc2 already has tzname/timezone, but initialized to wrong
values.)
I am pretty sure date/time arithmetic on Postgres should be changed
accordingly. Where can I start in postgres sources? Anyone to help?
Oleg.
---- Oleg Broytmann http://members.tripod.com/~phd2/ phd2@earthling.net Programmers don't die, they
justGOSUB without RETURN.
pgsql-hackers by date: