Date/time fixes for HAVE_TM_ZONE platforms - Mailing list pgsql-hackers

From Thomas G. Lockhart
Subject Date/time fixes for HAVE_TM_ZONE platforms
Date
Msg-id 368BAD2F.BFA181B3@alumni.caltech.edu
Whole thread Raw
Responses Re: Date/time fixes for HAVE_TM_ZONE platforms
Re: Date/time fixes for HAVE_TM_ZONE platforms
List pgsql-hackers
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 */

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] psql: stdout or stderr?
Next
From: Bruce Momjian
Date:
Subject: Unused_oids