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:

Previous
From: "Hiroshi Inoue"
Date:
Subject: Projecting attributes of function return values
Next
From: "Jackson, DeJuan"
Date:
Subject: RE: [HACKERS] DROPping tables with SERIALs