From 261026575d4b38fd7a39a43c53064de464695f0e Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Fri, 22 Jul 2005 21:16:15 +0000 Subject: [PATCH] Fix AT TIME ZONE for timestamps without time zones: test=> select ('2005-07-20 00:00:00'::timestamp without time zone) at time zone 'Europe/Paris'; timezone ------------------------ 2005-07-19 22:00:00-04 Udpate documentation. --- doc/src/sgml/func.sgml | 18 +++++++++--------- src/backend/utils/adt/timestamp.c | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 43f720ae10f..59813e16f16 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.268 2005/07/20 16:42:29 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.269 2005/07/22 21:16:14 momjian Exp $ PostgreSQL documentation --> @@ -5693,7 +5693,7 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); <literal><type>timestamp without time zone</type> AT TIME ZONE <replaceable>zone</></literal> </entry> <entry><type>timestamp with time zone</type></entry> - <entry>Convert local time in given time zone to UTC</entry> + <entry>Treat given timestamp <emphasis>without time zone</> as located in the specified time zone</entry> </row> <row> @@ -5701,7 +5701,7 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); <literal><type>timestamp with time zone</type> AT TIME ZONE <replaceable>zone</></literal> </entry> <entry><type>timestamp without time zone</type></entry> - <entry>Convert UTC to local time in given time zone</entry> + <entry>Convert given timestamp <emphasis>with time zone</> to the new time zone</entry> </row> <row> @@ -5709,7 +5709,7 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); <literal><type>time with time zone</type> AT TIME ZONE <replaceable>zone</></literal> </entry> <entry><type>time with time zone</type></entry> - <entry>Convert local time across time zones</entry> + <entry>Convert given time <emphasis>with time zone</> to the new time zone</entry> </row> </tbody> </tgroup> @@ -5720,7 +5720,8 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); specified either as a text string (e.g., <literal>'PST'</literal>) or as an interval (e.g., <literal>INTERVAL '-08:00'</literal>). In the text case, the available zone names are those shown in - <xref linkend="datetime-timezone-set-table">. + <xref linkend="datetime-timezone-set-table">. The time zone can + also be implied using the default time zone for that session. </para> <para> @@ -5732,10 +5733,9 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST'; SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST'; <lineannotation>Result: </lineannotation><computeroutput>2001-02-16 18:38:40</computeroutput> </screen> - The first example takes a zone-less time stamp and interprets it as MST time - (UTC-7) to produce a UTC time stamp, which is then rotated to PST (UTC-8) - for display. The second example takes a time stamp specified in EST - (UTC-5) and converts it to local time in MST (UTC-7). + The first example takes a time stamp without time zone and interprets it as MST time + (UTC-7), which is then converted to PST (UTC-8) for display. The second example takes + a time stamp specified in EST (UTC-5) and converts it to local time in MST (UTC-7). </para> <para> diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 73a68a1a22e..2d9b5ad7d0d 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.141 2005/07/22 19:00:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.142 2005/07/22 21:16:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1035,7 +1035,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn, #endif /* add offset to go from J2000 back to standard Julian date */ - date +=POSTGRES_EPOCH_JDATE; + date += POSTGRES_EPOCH_JDATE; /* Julian day routine does not work for negative Julian days */ if (date <0 || date >(Timestamp) INT_MAX) @@ -1147,8 +1147,8 @@ tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result) return -1; date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; - time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec); + #ifdef HAVE_INT64_TIMESTAMP *result = date * USECS_PER_DAY + time; /* check for major overflow */ @@ -2673,7 +2673,7 @@ timestamp_text(PG_FUNCTION_ARGS) result = palloc(len); VARATT_SIZEP(result) = len; - memmove(VARDATA(result), str, (len - VARHDRSZ)); + memmove(VARDATA(result), str, len - VARHDRSZ); pfree(str); @@ -2704,7 +2704,7 @@ text_timestamp(PG_FUNCTION_ARGS) sp = VARDATA(str); dp = dstr; - for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) + for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++) *dp++ = *sp++; *dp = '\0'; @@ -2729,12 +2729,12 @@ timestamptz_text(PG_FUNCTION_ARGS) str = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp)); - len = (strlen(str) + VARHDRSZ); + len = strlen(str) + VARHDRSZ; result = palloc(len); VARATT_SIZEP(result) = len; - memmove(VARDATA(result), str, (len - VARHDRSZ)); + memmove(VARDATA(result), str, len - VARHDRSZ); pfree(str); @@ -2764,7 +2764,7 @@ text_timestamptz(PG_FUNCTION_ARGS) sp = VARDATA(str); dp = dstr; - for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) + for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++) *dp++ = *sp++; *dp = '\0'; @@ -2789,7 +2789,7 @@ interval_text(PG_FUNCTION_ARGS) str = DatumGetCString(DirectFunctionCall1(interval_out, IntervalPGetDatum(interval))); - len = (strlen(str) + VARHDRSZ); + len = strlen(str) + VARHDRSZ; result = palloc(len); @@ -3084,7 +3084,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS) case DTK_MILLISEC: #ifdef HAVE_INT64_TIMESTAMP - fsec = ((fsec / 1000) * 1000); + fsec = (fsec / 1000) * 1000; #else fsec = rint(fsec * 1000) / 1000; #endif @@ -3181,7 +3181,7 @@ interval_trunc(PG_FUNCTION_ARGS) case DTK_MILLISEC: #ifdef HAVE_INT64_TIMESTAMP - fsec = ((fsec / 1000) * 1000); + fsec = (fsec / 1000) * 1000; #else fsec = rint(fsec * 1000) / 1000; #endif @@ -3932,7 +3932,7 @@ timestamp_zone(PG_FUNCTION_ARGS) { text *zone = PG_GETARG_TEXT_P(0); Timestamp timestamp = PG_GETARG_TIMESTAMP(1); - Timestamp result; + TimestampTz result; int tz; pg_tz *tzp; char tzname[TZ_STRLEN_MAX+1]; @@ -3968,7 +3968,7 @@ timestamp_zone(PG_FUNCTION_ARGS) tzname))); PG_RETURN_NULL(); } - PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(result)); + PG_RETURN_TIMESTAMPTZ(result); } /* timestamp_izone() -- GitLab