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: