Here are some patches which fix the recently reported date/time problems
on linux/glibc2 machines. Note that these will also fix any machine
which "tests positive" for HAVE_TM_ZONE, which might include SunOS and
xBSD machines.
The symptom can be demonstrated by the following query:
select datetime('2000-01-01'::date);
which, if there is a problem, will return a time away from midnight.
Note that your time zone must be set to something other than GMT for
this test to be meaningful.
Thanks Oleg for being persistant!
- Tom*** ../src/backend/utils/adt/datetime.c.orig Tue Sep 1 03:25:54 1998
--- ../src/backend/utils/adt/datetime.c Thu Dec 31 16:19:56 1998
***************
*** 339,345 ****
* and then convert again to try to get the time zones correct.
*/
static int
! date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn)
{
struct tm *tx;
time_t utime;
--- 339,345 ----
* and then convert again to try to get the time zones correct.
*/
static int
! date2tm(DateADT dateVal, int *tzp, struct tm *tm, double *fsec, char **tzn)
{
struct tm *tx;
time_t utime;
***************
*** 357,370 ****
/* convert to system time */
utime = ((dateVal + (date2j(2000, 1, 1) - date2j(1970, 1, 1))) * 86400);
! utime += (12 * 60 * 60);/* rotate to noon to get the right day in
! * time zone */
#ifdef USE_POSIX_TIME
tx = localtime(&utime);
#ifdef DATEDEBUG
! #ifdef HAVE_INT_TIMEZONE
printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
tzname[0], tzname[1], tx->tm_isdst);
--- 357,374 ----
/* convert to system time */
utime = ((dateVal + (date2j(2000, 1, 1) - date2j(1970, 1, 1))) * 86400);
! /* rotate to noon to get the right day in time zone */
! utime += (12 * 60 * 60);
#ifdef USE_POSIX_TIME
tx = localtime(&utime);
#ifdef DATEDEBUG
! #if defined(HAVE_TM_ZONE)
! printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n",
! tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
! tx->tm_zone, tx->tm_isdst);
! #elif defined(HAVE_INT_TIMEZONE)
printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
tzname[0], tzname[1], tx->tm_isdst);
***************
*** 375,395 ****
tm->tm_mday = tx->tm_mday;
tm->tm_isdst = tx->tm_isdst;
! #ifdef HAVE_INT_TIMEZONE
! *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
! if (tzn != NULL)
! *tzn = tzname[(tm->tm_isdst > 0)];
!
! #else /* !HAVE_INT_TIMEZONE */
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
! *tzp = (tm->tm_isdst ? (tm->tm_gmtoff - 3600) : tm->tm_gmtoff); /* tm_gmtoff is
! * Sun/DEC-ism */
if (tzn != NULL)
! *tzn = tm->tm_zone;
#endif
-
#else /* !USE_POSIX_TIME */
*tzp = CTimeZone; /* V7 conventions; don't know timezone? */
if (tzn != NULL)
--- 379,399 ----
tm->tm_mday = tx->tm_mday;
tm->tm_isdst = tx->tm_isdst;
! #if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
! /* tm_gmtoff is Sun/DEC-ism */
! *tzp = -(tm->tm_gmtoff);
! if (tzn != NULL)
! *tzn = (char *)tm->tm_zone;
! #elif defined(HAVE_INT_TIMEZONE)
! *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
if (tzn != NULL)
! *tzn = tzname[(tm->tm_isdst > 0)];
! #else
! #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#else /* !USE_POSIX_TIME */
*tzp = CTimeZone; /* V7 conventions; don't know timezone? */
if (tzn != NULL)
***************
*** 410,415 ****
--- 414,431 ----
if (tzn != NULL)
*tzn = NULL;
}
+
+ #ifdef DATEDEBUG
+ #if defined(HAVE_TM_ZONE)
+ printf("date2tm- %d.%02d.%02d %02d:%02d:%02.0f (%d %s) dst=%d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, (double) tm->tm_sec,
+ *tzp, tm->tm_zone, tm->tm_isdst);
+ #elif defined(HAVE_INT_TIMEZONE)
+ printf("date2tm- %d.%02d.%02d %02d:%02d:%02.0f (%d %s %s) dst=%d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, (double) tm->tm_sec,
+ *tzp, tzname[0], tzname[1], tm->tm_isdst);
+ #endif
+ #endif
return 0;
} /* date2tm() */
*** ../src/backend/utils/adt/dt.c.orig Thu Oct 8 18:30:07 1998
--- ../src/backend/utils/adt/dt.c Thu Dec 31 16:19:46 1998
***************
*** 1454,1464 ****
tm->tm_year += 1900;
tm->tm_mon += 1;
! #ifdef HAVE_INT_TIMEZONE
! tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
!
! #else /* !HAVE_INT_TIMEZONE */
tz = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#endif
#else /* !USE_POSIX_TIME */
--- 1454,1465 ----
tm->tm_year += 1900;
tm->tm_mon += 1;
! #if defined(HAVE_TM_ZONE)
tz = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+ #elif defined(HAVE_INT_TIMEZONE)
+ tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
+ #else
+ #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#else /* !USE_POSIX_TIME */
***************
*** 2414,2429 ****
#ifdef USE_POSIX_TIME
tx = localtime(&utime);
#ifdef DATEDEBUG
! #ifdef HAVE_INT_TIMEZONE
printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
tzname[0], tzname[1], tx->tm_isdst);
#else
! printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n",
! tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
! tx->tm_zone, tx->tm_isdst);
#endif
- #else
#endif
tm->tm_year = tx->tm_year + 1900;
tm->tm_mon = tx->tm_mon + 1;
--- 2415,2431 ----
#ifdef USE_POSIX_TIME
tx = localtime(&utime);
#ifdef DATEDEBUG
! #if defined(HAVE_TM_ZONE)
! printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n",
! tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
! tx->tm_zone, tx->tm_isdst);
! #elif defined(HAVE_INT_TIMEZONE)
printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
tzname[0], tzname[1], tx->tm_isdst);
#else
! #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#endif
tm->tm_year = tx->tm_year + 1900;
tm->tm_mon = tx->tm_mon + 1;
***************
*** 2442,2459 ****
#endif
tm->tm_isdst = tx->tm_isdst;
! #ifdef HAVE_INT_TIMEZONE
! *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
! if (tzn != NULL)
! *tzn = tzname[(tm->tm_isdst > 0)];
!
! #else /* !HAVE_INT_TIMEZONE */
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
*tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
if (tzn != NULL)
! *tzn = tm->tm_zone;
#endif
#else /* !USE_POSIX_TIME */
--- 2444,2462 ----
#endif
tm->tm_isdst = tx->tm_isdst;
! #if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
*tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
if (tzn != NULL)
! *tzn = (char *)tm->tm_zone;
! #elif defined(HAVE_INT_TIMEZONE)
! *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
! if (tzn != NULL)
! *tzn = tzname[(tm->tm_isdst > 0)];
! #else
! #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#else /* !USE_POSIX_TIME */
***************
*** 2488,2494 ****
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
! #ifdef HAVE_INT_TIMEZONE
printf("datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
tzname[tm->tm_isdst != 0], ((tzp != NULL) ? *tzp : 0), CTimeZone, CDayLight);
#endif
--- 2491,2500 ----
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
! #if defined(HAVE_TM_ZONE)
! printf("datetime2tm- timezone is %s; offset is %d\n",
! tm->tm_zone, ((tzp != NULL) ? *tzp : 0));
! #elif defined(HAVE_INT_TIMEZONE)
printf("datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
tzname[tm->tm_isdst != 0], ((tzp != NULL) ? *tzp : 0), CTimeZone, CDayLight);
#endif
***************
*** 3034,3044 ****
tm->tm_year += 1900;
tm->tm_mon += 1;
! #ifdef HAVE_INT_TIMEZONE
! *tzp = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
!
! #else /* !HAVE_INT_TIMEZONE */
*tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#endif
#else /* !USE_POSIX_TIME */
--- 3040,3051 ----
tm->tm_year += 1900;
tm->tm_mon += 1;
! #if defined(HAVE_TM_ZONE)
*tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+ #elif defined(HAVE_INT_TIMEZONE)
+ *tzp = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
+ #else
+ #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#else /* !USE_POSIX_TIME */
***************
*** 4104,4115 ****
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
! #ifdef HAVE_INT_TIMEZONE
printf("EncodeDateTime- timezone is %s (%s); offset is %d (%d); daylight is %d (%d)\n",
*tzn, tzname[0], *tzp, CTimeZone, tm->tm_isdst, CDayLight);
#else
! printf("EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
! *tzn, tm->tm_zone, (-tm->tm_gmtoff), CTimeZone, tm->tm_isdst, CDayLight);
#endif
#else
printf("EncodeDateTime- timezone is %s (%s); offset is %d; daylight is %d\n",
--- 4111,4124 ----
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
! #if defined(HAVE_TM_ZONE)
! printf("EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
! *tzn, tm->tm_zone, (-tm->tm_gmtoff), CTimeZone, tm->tm_isdst, CDayLight);
! #elif defined(HAVE_INT_TIMEZONE)
printf("EncodeDateTime- timezone is %s (%s); offset is %d (%d); daylight is %d (%d)\n",
*tzn, tzname[0], *tzp, CTimeZone, tm->tm_isdst, CDayLight);
#else
! #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
#endif
#else
printf("EncodeDateTime- timezone is %s (%s); offset is %d; daylight is %d\n",
*** ../src/backend/utils/adt/nabstime.c.orig Sun Dec 20 17:35:40 1998
--- ../src/backend/utils/adt/nabstime.c Thu Dec 31 16:19:51 1998
***************
*** 57,63 ****
if (!HasCTZSet)
{
#ifdef USE_POSIX_TIME
! #ifdef HAVE_TM_ZONE
tm = localtime(&now);
CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
--- 57,63 ----
if (!HasCTZSet)
{
#ifdef USE_POSIX_TIME
! #if defined(HAVE_TM_ZONE)
tm = localtime(&now);
CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
***************
*** 86,94 ****
CTimeZone = tb.timezone * 60;
CDayLight = (tb.dstflag != 0);
! /*
! * XXX does this work to get the local timezone string in V7? -
! * tgl 97/03/18
*/
strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
--- 86,93 ----
CTimeZone = tb.timezone * 60;
CDayLight = (tb.dstflag != 0);
! /* XXX does this work to get the local timezone string in V7?
! * - tgl 97/03/18
*/
strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
***************
*** 136,149 ****
#endif
#if defined(DATEDEBUG)
! #if (! defined(HAVE_TM_ZONE)) && defined(HAVE_INT_TIMEZONE)
! printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n",
! tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
! tzname[0], tzname[1], tx->tm_isdst);
! #else
printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
tx->tm_zone, tx->tm_isdst);
#endif
#endif
--- 135,148 ----
#endif
#if defined(DATEDEBUG)
! #if defined(HAVE_TM_ZONE)
printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n",
tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
tx->tm_zone, tx->tm_isdst);
+ #elif defined(HAVE_INT_TIMEZONE)
+ printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
+ tzname[0], tzname[1], tx->tm_isdst);
#endif
#endif
***************
*** 157,163 ****
tm->tm_sec = tx->tm_sec;
tm->tm_isdst = tx->tm_isdst;
! #ifdef HAVE_TM_ZONE
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
--- 156,162 ----
tm->tm_sec = tx->tm_sec;
tm->tm_isdst = tx->tm_isdst;
! #if defined(HAVE_TM_ZONE)
tm->tm_gmtoff = tx->tm_gmtoff;
tm->tm_zone = tx->tm_zone;
***************
*** 171,177 ****
*tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
if (tzn != NULL)
strcpy(tzn, tzname[tm->tm_isdst]);
! #else /* !HAVE_INT_TIMEZONE */
#error POSIX time support is broken
#endif
#else /* ! USE_POSIX_TIME */
--- 170,176 ----
*tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
if (tzn != NULL)
strcpy(tzn, tzname[tm->tm_isdst]);
! #else
#error POSIX time support is broken
#endif
#else /* ! USE_POSIX_TIME */