diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 0bea16cb67..9e8baeaa9c 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -1481,9 +1481,7 @@ float_time_overflows(int hour, int min, double sec) /* time2tm() * Convert time data type to POSIX time structure. * - * For dates within the range of pg_time_t, convert to the local time zone. - * If out of this range, leave as UTC (in practice that could only happen - * if pg_time_t is just 32 bits) - thomas 97/05/27 + * Note that only the hour/min/sec/fractional-sec fields are filled in. */ int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec) @@ -3029,7 +3027,7 @@ extract_timetz(PG_FUNCTION_ARGS) /* timetz_zone() * Encode time with time zone type with specified time zone. - * Applies DST rules as of the current date. + * Applies DST rules as of the transaction start time. */ Datum timetz_zone(PG_FUNCTION_ARGS) @@ -3068,12 +3066,11 @@ timetz_zone(PG_FUNCTION_ARGS) } else if (type == DYNTZ) { - /* dynamic-offset abbreviation, resolve using current time */ - pg_time_t now = (pg_time_t) time(NULL); - struct pg_tm *tm; + /* dynamic-offset abbreviation, resolve using transaction start time */ + TimestampTz now = GetCurrentTransactionStartTimestamp(); + int isdst; - tm = pg_localtime(&now, tzp); - tz = DetermineTimeZoneAbbrevOffset(tm, tzname, tzp); + tz = DetermineTimeZoneAbbrevOffsetTS(now, tzname, tzp, &isdst); } else { @@ -3081,12 +3078,15 @@ timetz_zone(PG_FUNCTION_ARGS) tzp = pg_tzset(tzname); if (tzp) { - /* Get the offset-from-GMT that is valid today for the zone */ - pg_time_t now = (pg_time_t) time(NULL); - struct pg_tm *tm; + /* Get the offset-from-GMT that is valid now for the zone */ + TimestampTz now = GetCurrentTransactionStartTimestamp(); + struct pg_tm tm; + fsec_t fsec; - tm = pg_localtime(&now, tzp); - tz = -tm->tm_gmtoff; + if (timestamp2tm(now, &tz, &tm, &fsec, NULL, tzp) != 0) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range"))); } else { diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 3190d82a86..fb35d3d5be 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202109032 +#define CATALOG_VERSION_NO 202109061 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index c07b2c6a55..d068d6532e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5953,7 +5953,7 @@ proname => 'timestamp_larger', prorettype => 'timestamp', proargtypes => 'timestamp timestamp', prosrc => 'timestamp_larger' }, { oid => '2037', descr => 'adjust time with time zone to new zone', - proname => 'timezone', provolatile => 'v', prorettype => 'timetz', + proname => 'timezone', provolatile => 's', prorettype => 'timetz', proargtypes => 'text timetz', prosrc => 'timetz_zone' }, { oid => '2038', descr => 'adjust time with time zone to new zone', proname => 'timezone', prorettype => 'timetz',