diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index d003c4ee51689109ee1cd119f70db05968a31094..ba1b7f6a4d25562d062183c78719018fb2eee015 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -25,10 +25,6 @@ #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); } diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 45ad968f2c77609e2c80057706125e88dc8e66e6..39a39c479d7c30f1c4095f0f6aa12fc96373ce48 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -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)