Date/time on glibc2 linux

From: Oleg Broytmann <phd(at)sun(dot)med(dot)ru>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Date/time on glibc2 linux
Date: 1998-12-03 18:59:42
Message-ID: Pine.SOL2.3.96.SK.981203213845.18181A-100000@sun.med.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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;
char wintername[10], summername[10];
/* XXX This won't work on the southern hemisphere.
XXX Anybody got a better idea? */
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(at)earthling(dot)net
Programmers don't die, they just GOSUB without RETURN.

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jackson, DeJuan 1998-12-03 19:49:40 RE: [HACKERS] DROPping tables with SERIALs
Previous Message Constantin Teodorescu 1998-12-03 18:32:55 Two ugly bugs in pg_dump :-(