]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Modify date->timestamp conversion to use mktime().
authorThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 12 Sep 2000 05:41:37 +0000 (05:41 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 12 Sep 2000 05:41:37 +0000 (05:41 +0000)
 This should do better than before around Daylight Savings Time
 transitions.

src/backend/utils/adt/date.c
src/backend/utils/adt/datetime.c

index d003c4ee51689109ee1cd119f70db05968a31094..ba1b7f6a4d25562d062183c78719018fb2eee015 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.49 2000/07/12 22:59:08 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.50 2000/09/12 05:41:37 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "utils/nabstime.h"
 
 
-static int date2tm(DateADT dateVal, int *tzp, struct tm * tm,
-                                  double *fsec, char **tzn);
-
-
 /*****************************************************************************
  *      Date ADT
  *****************************************************************************/
@@ -230,15 +226,34 @@ date_timestamp(PG_FUNCTION_ARGS)
        Timestamp       result;
        struct tm       tt,
                           *tm = &tt;
-       int                     tz;
-       double          fsec = 0;
-       char       *tzn;
+       time_t          utime;
 
-       if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0)
-               elog(ERROR, "Unable to convert date to timestamp");
+       j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
 
-       if (tm2timestamp(tm, fsec, &tz, &result) != 0)
-               elog(ERROR, "Timestamp out of range");
+       if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+       {
+#ifdef USE_POSIX_TIME
+               tm->tm_hour = 0;
+               tm->tm_min = 0;
+               tm->tm_sec = 0;
+               tm->tm_isdst = -1;
+
+               tm->tm_year -= 1900;
+               tm->tm_mon -= 1;
+               utime = mktime(tm);
+               if (utime == -1)
+                       elog(ERROR, "Unable to convert date to tm");
+
+               result = utime + ((date2j(1970,1,1)-date2j(2000,1,1))*86400.0);
+#else                                                  /* !USE_POSIX_TIME */
+               result = dateVal*86400.0+CTimeZone;
+#endif
+       }
+       else
+       {
+               /* Outside of range for timezone support, so assume UTC */
+               result = dateVal*86400.0;
+       }
 
        PG_RETURN_TIMESTAMP(result);
 }
@@ -324,81 +339,6 @@ abstime_date(PG_FUNCTION_ARGS)
 }
 
 
-/* date2tm()
- * Convert date to time structure.
- * Note that date is an implicit local time, but the system calls assume
- *     that everything is GMT. So, convert to GMT, rotate to local time,
- *     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;
-
-       *fsec = 0;
-
-       j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
-       tm->tm_hour = 0;
-       tm->tm_min = 0;
-       tm->tm_sec = 0;
-       tm->tm_isdst = -1;
-
-       if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
-       {
-
-               /* 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);
-
-               tm->tm_year = tx->tm_year + 1900;
-               tm->tm_mon = tx->tm_mon + 1;
-               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)
-#ifdef __CYGWIN__
-               *tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
-#else
-               *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
-#endif
-               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)
-                       *tzn = CTZName;
-#endif
-
-               /* otherwise, outside of timezone range so convert to GMT... */
-       }
-       else
-       {
-               *tzp = 0;
-               tm->tm_isdst = 0;
-               if (tzn != NULL)
-                       *tzn = NULL;
-       }
-
-       return 0;
-}      /* date2tm() */
-
-
 /*****************************************************************************
  *      Time ADT
  *****************************************************************************/
@@ -906,19 +846,8 @@ datetimetz_timestamp(PG_FUNCTION_ARGS)
        DateADT         date = PG_GETARG_DATEADT(0);
        TimeTzADT  *time = PG_GETARG_TIMETZADT_P(1);
        Timestamp       result;
-       struct tm       tt,
-                          *tm = &tt;
-       int                     tz;
-       double          fsec = 0;
-       char       *tzn;
-
-       if (date2tm(date, &tz, tm, &fsec, &tzn) != 0)
-               elog(ERROR, "Unable to convert date to timestamp");
-
-       if (tm2timestamp(tm, fsec, &time->zone, &result) != 0)
-               elog(ERROR, "Timestamp out of range");
 
-       result += time->time;
+       result = date*86400.0 + time->time + time->zone;
 
        PG_RETURN_TIMESTAMP(result);
 }
index 45ad968f2c77609e2c80057706125e88dc8e66e6..39a39c479d7c30f1c4095f0f6aa12fc96373ce48 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.52 2000/07/14 15:33:33 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.53 2000/09/12 05:41:37 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2247,8 +2247,8 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
                        sprintf(cp, "%s%02d:%02d", (is_nonzero ? " " : ""),
                                        abs(tm->tm_hour), abs(tm->tm_min));
                        cp += strlen(cp);
-                       if ((tm->tm_hour != 0) || (tm->tm_min != 0))
-                               is_nonzero = TRUE;
+                       /* Mark as "non-zero" since the fields are now filled in */
+                       is_nonzero = TRUE;
 
                        /* fractional seconds? */
                        if (fsec != 0)