Index: src/backend/utils/adt/date.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/date.c,v retrieving revision 1.118 diff -c -c -r1.118 date.c *** src/backend/utils/adt/date.c 22 Jul 2005 05:03:09 -0000 1.118 --- src/backend/utils/adt/date.c 23 Jul 2005 14:23:14 -0000 *************** *** 301,307 **** tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; ! tz = DetermineLocalTimeZone(tm); #ifdef HAVE_INT64_TIMESTAMP result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC; --- 301,307 ---- tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; ! tz = DetermineTimeZoneOffset(tm, global_timezone); #ifdef HAVE_INT64_TIMESTAMP result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC; *************** *** 2231,2237 **** GetCurrentDateTime(tm); time2tm(time, tm, &fsec); ! tz = DetermineLocalTimeZone(tm); result = (TimeTzADT *) palloc(sizeof(TimeTzADT)); --- 2231,2237 ---- GetCurrentDateTime(tm); time2tm(time, tm, &fsec); ! tz = DetermineTimeZoneOffset(tm, global_timezone); result = (TimeTzADT *) palloc(sizeof(TimeTzADT)); Index: src/backend/utils/adt/datetime.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v retrieving revision 1.156 diff -c -c -r1.156 datetime.c *** src/backend/utils/adt/datetime.c 22 Jul 2005 03:46:33 -0000 1.156 --- src/backend/utils/adt/datetime.c 23 Jul 2005 14:23:15 -0000 *************** *** 1612,1618 **** if (fmask & DTK_M(DTZMOD)) return DTERR_BAD_FORMAT; ! *tzp = DetermineLocalTimeZone(tm); } } --- 1612,1618 ---- if (fmask & DTK_M(DTZMOD)) return DTERR_BAD_FORMAT; ! *tzp = DetermineTimeZoneOffset(tm, global_timezone); } } *************** *** 1620,1629 **** } ! /* DetermineLocalTimeZone() * * Given a struct pg_tm in which tm_year, tm_mon, tm_mday, tm_hour, tm_min, and ! * tm_sec fields are set, attempt to determine the applicable local zone * (ie, regular or daylight-savings time) at that time. Set the struct pg_tm's * tm_isdst field accordingly, and return the actual timezone offset. * --- 1620,1629 ---- } ! /* DetermineTimeZoneOffset() * * Given a struct pg_tm in which tm_year, tm_mon, tm_mday, tm_hour, tm_min, and ! * tm_sec fields are set, attempt to determine the applicable time zone * (ie, regular or daylight-savings time) at that time. Set the struct pg_tm's * tm_isdst field accordingly, and return the actual timezone offset. * *************** *** 1632,1638 **** * of mktime(), anyway. */ int ! DetermineLocalTimeZone(struct pg_tm *tm) { int date, sec; --- 1632,1638 ---- * of mktime(), anyway. */ int ! DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp) { int date, sec; *************** *** 1648,1654 **** after_isdst; int res; ! if (HasCTZSet) { tm->tm_isdst = 0; /* for lack of a better idea */ return CTimeZone; --- 1648,1654 ---- after_isdst; int res; ! if (tzp == global_timezone && HasCTZSet) { tm->tm_isdst = 0; /* for lack of a better idea */ return CTimeZone; *************** *** 1687,1693 **** &before_gmtoff, &before_isdst, &boundary, &after_gmtoff, &after_isdst, ! global_timezone); if (res < 0) goto overflow; /* failure? */ --- 1687,1693 ---- &before_gmtoff, &before_isdst, &boundary, &after_gmtoff, &after_isdst, ! tzp); if (res < 0) goto overflow; /* failure? */ *************** *** 2282,2288 **** tmp->tm_hour = tm->tm_hour; tmp->tm_min = tm->tm_min; tmp->tm_sec = tm->tm_sec; ! *tzp = DetermineLocalTimeZone(tmp); tm->tm_isdst = tmp->tm_isdst; } --- 2282,2288 ---- tmp->tm_hour = tm->tm_hour; tmp->tm_min = tm->tm_min; tmp->tm_sec = tm->tm_sec; ! *tzp = DetermineTimeZoneOffset(tmp, global_timezone); tm->tm_isdst = tmp->tm_isdst; } Index: src/backend/utils/adt/formatting.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v retrieving revision 1.92 diff -c -c -r1.92 formatting.c *** src/backend/utils/adt/formatting.c 21 Jul 2005 03:56:16 -0000 1.92 --- src/backend/utils/adt/formatting.c 23 Jul 2005 14:23:17 -0000 *************** *** 2989,2995 **** do_to_timestamp(date_txt, fmt, &tm, &fsec); ! tz = DetermineLocalTimeZone(&tm); if (tm2timestamp(&tm, fsec, &tz, &result) != 0) ereport(ERROR, --- 2989,2995 ---- do_to_timestamp(date_txt, fmt, &tm, &fsec); ! tz = DetermineTimeZoneOffset(&tm, global_timezone); if (tm2timestamp(&tm, fsec, &tz, &result) != 0) ereport(ERROR, Index: src/backend/utils/adt/nabstime.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v retrieving revision 1.141 diff -c -c -r1.141 nabstime.c *** src/backend/utils/adt/nabstime.c 22 Jul 2005 19:55:50 -0000 1.141 --- src/backend/utils/adt/nabstime.c 23 Jul 2005 14:23:18 -0000 *************** *** 474,480 **** result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) { ! tz = DetermineLocalTimeZone(tm); result = tm2abstime(tm, tz); } else --- 474,480 ---- result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) { ! tz = DetermineTimeZoneOffset(tm, global_timezone); result = tm2abstime(tm, tz); } else Index: src/backend/utils/adt/timestamp.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v retrieving revision 1.143 diff -c -c -r1.143 timestamp.c *** src/backend/utils/adt/timestamp.c 23 Jul 2005 02:02:27 -0000 1.143 --- src/backend/utils/adt/timestamp.c 23 Jul 2005 14:23:19 -0000 *************** *** 2100,2106 **** if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]); ! tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) ereport(ERROR, --- 2100,2106 ---- if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]); ! tz = DetermineTimeZoneOffset(tm, global_timezone); if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) ereport(ERROR, *************** *** 2124,2130 **** julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day; j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); ! tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) ereport(ERROR, --- 2124,2130 ---- julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day; j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); ! tz = DetermineTimeZoneOffset(tm, global_timezone); if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) ereport(ERROR, *************** *** 3104,3110 **** } if (redotz) ! tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, &result) != 0) ereport(ERROR, --- 3104,3110 ---- } if (redotz) ! tz = DetermineTimeZoneOffset(tm, global_timezone); if (tm2timestamp(tm, fsec, &tz, &result) != 0) ereport(ERROR, *************** *** 3529,3535 **** (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); ! tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0) ereport(ERROR, --- 3529,3535 ---- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); ! tz = DetermineTimeZoneOffset(tm, global_timezone); if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0) ereport(ERROR, *************** *** 3924,3935 **** /* timestamp_zone() * Encode timestamp type with specified time zone. ! * Returns timestamp with time zone, with the input ! * rotated from local time to the specified zone. ! * This function is tricky because instead of shifting ! * the time _to_ a new time zone, it sets the time to _be_ ! * the specified timezone. This requires trickery ! * of double-subtracting the requested timezone offset. */ Datum timestamp_zone(PG_FUNCTION_ARGS) --- 3924,3934 ---- /* timestamp_zone() * Encode timestamp type with specified time zone. ! * This function is just timestamp2timestamptz() except instead of ! * shifting to the global timezone, we shift to the specified timezone. ! * This is different from the other AT TIME ZONE cases because instead ! * of shifting to a _to_ a new time zone, it sets the time to _be_ the ! * specified timezone. */ Datum timestamp_zone(PG_FUNCTION_ARGS) *************** *** 3943,3953 **** int len; struct pg_tm tm; fsec_t fsec; ! if (TIMESTAMP_NOT_FINITE(timestamp)) PG_RETURN_TIMESTAMPTZ(timestamp); ! /* Find the specified timezone? */ len = (VARSIZE(zone) - VARHDRSZ>TZ_STRLEN_MAX) ? TZ_STRLEN_MAX : VARSIZE(zone) - VARHDRSZ; memcpy(tzname, VARDATA(zone), len); --- 3942,3953 ---- int len; struct pg_tm tm; fsec_t fsec; ! bool fail; ! if (TIMESTAMP_NOT_FINITE(timestamp)) PG_RETURN_TIMESTAMPTZ(timestamp); ! /* Find the specified timezone */ len = (VARSIZE(zone) - VARHDRSZ>TZ_STRLEN_MAX) ? TZ_STRLEN_MAX : VARSIZE(zone) - VARHDRSZ; memcpy(tzname, VARDATA(zone), len); *************** *** 3963,3970 **** } /* Apply the timezone change */ ! if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0 || ! tm2timestamp(&tm, fsec, &tz, &result) != 0) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), --- 3963,3975 ---- } /* Apply the timezone change */ ! fail = (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0); ! if (!fail) ! { ! tz = DetermineTimeZoneOffset(&tm, tzp); ! fail = (tm2timestamp(&tm, fsec, &tz, &result) != 0); ! } ! if (fail) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), *************** *** 3972,3979 **** tzname))); PG_RETURN_NULL(); } - /* Must double-adjust for timezone */ - result = dt2local(result, -tz); PG_RETURN_TIMESTAMPTZ(result); } --- 3977,3982 ---- *************** *** 4039,4045 **** (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); ! tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, &result) != 0) ereport(ERROR, --- 4042,4048 ---- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); ! tz = DetermineTimeZoneOffset(tm, global_timezone); if (tm2timestamp(tm, fsec, &tz, &result) != 0) ereport(ERROR, Index: src/include/utils/datetime.h =================================================================== RCS file: /cvsroot/pgsql/src/include/utils/datetime.h,v retrieving revision 1.55 diff -c -c -r1.55 datetime.h *** src/include/utils/datetime.h 22 Jul 2005 03:46:34 -0000 1.55 --- src/include/utils/datetime.h 23 Jul 2005 14:23:20 -0000 *************** *** 291,297 **** extern void DateTimeParseError(int dterr, const char *str, const char *datatype); ! extern int DetermineLocalTimeZone(struct pg_tm *tm); extern int EncodeDateOnly(struct pg_tm *tm, int style, char *str); extern int EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, int *tzp, int style, char *str); --- 291,297 ---- extern void DateTimeParseError(int dterr, const char *str, const char *datatype); ! extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp); extern int EncodeDateOnly(struct pg_tm *tm, int style, char *str); extern int EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, int *tzp, int style, char *str);