Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3dbbbbf

Browse files
committed
Andrew pointed out that the current fix didn't handle dates that were
near daylight savings time boudaries. This handles it properly, e.g. test=> select '2005-04-03 04:00:00'::timestamp at time zone 'America/Los_Angeles'; timezone ------------------------ 2005-04-03 07:00:00-04 (1 row)
1 parent6c61b0d commit3dbbbbf

File tree

6 files changed

+38
-35
lines changed

6 files changed

+38
-35
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.118 2005/07/22 05:03:09 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.119 2005/07/23 14:25:33 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -301,7 +301,7 @@ date2timestamptz(DateADT dateVal)
301301
tm->tm_hour=0;
302302
tm->tm_min=0;
303303
tm->tm_sec=0;
304-
tz=DetermineLocalTimeZone(tm);
304+
tz=DetermineTimeZoneOffset(tm,global_timezone);
305305

306306
#ifdefHAVE_INT64_TIMESTAMP
307307
result=dateVal*USECS_PER_DAY+tz*USECS_PER_SEC;
@@ -2231,7 +2231,7 @@ time_timetz(PG_FUNCTION_ARGS)
22312231

22322232
GetCurrentDateTime(tm);
22332233
time2tm(time,tm,&fsec);
2234-
tz=DetermineLocalTimeZone(tm);
2234+
tz=DetermineTimeZoneOffset(tm,global_timezone);
22352235

22362236
result= (TimeTzADT*)palloc(sizeof(TimeTzADT));
22372237

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.156 2005/07/22 03:46:33 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.157 2005/07/23 14:25:33 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1612,18 +1612,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
16121612
if (fmask&DTK_M(DTZMOD))
16131613
returnDTERR_BAD_FORMAT;
16141614

1615-
*tzp=DetermineLocalTimeZone(tm);
1615+
*tzp=DetermineTimeZoneOffset(tm,global_timezone);
16161616
}
16171617
}
16181618

16191619
return0;
16201620
}
16211621

16221622

1623-
/*DetermineLocalTimeZone()
1623+
/*DetermineTimeZoneOffset()
16241624
*
16251625
* Given a struct pg_tm in which tm_year, tm_mon, tm_mday, tm_hour, tm_min, and
1626-
* tm_sec fields are set, attempt to determine the applicablelocal zone
1626+
* tm_sec fields are set, attempt to determine the applicabletime zone
16271627
* (ie, regular or daylight-savings time) at that time. Set the struct pg_tm's
16281628
* tm_isdst field accordingly, and return the actual timezone offset.
16291629
*
@@ -1632,7 +1632,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
16321632
* of mktime(), anyway.
16331633
*/
16341634
int
1635-
DetermineLocalTimeZone(structpg_tm*tm)
1635+
DetermineTimeZoneOffset(structpg_tm*tm,pg_tz*tzp)
16361636
{
16371637
intdate,
16381638
sec;
@@ -1648,7 +1648,7 @@ DetermineLocalTimeZone(struct pg_tm *tm)
16481648
after_isdst;
16491649
intres;
16501650

1651-
if (HasCTZSet)
1651+
if (tzp==global_timezone&&HasCTZSet)
16521652
{
16531653
tm->tm_isdst=0;/* for lack of a better idea */
16541654
returnCTimeZone;
@@ -1687,7 +1687,7 @@ DetermineLocalTimeZone(struct pg_tm *tm)
16871687
&before_gmtoff,&before_isdst,
16881688
&boundary,
16891689
&after_gmtoff,&after_isdst,
1690-
global_timezone);
1690+
tzp);
16911691
if (res<0)
16921692
gotooverflow;/* failure? */
16931693

@@ -2282,7 +2282,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
22822282
tmp->tm_hour=tm->tm_hour;
22832283
tmp->tm_min=tm->tm_min;
22842284
tmp->tm_sec=tm->tm_sec;
2285-
*tzp=DetermineLocalTimeZone(tmp);
2285+
*tzp=DetermineTimeZoneOffset(tmp,global_timezone);
22862286
tm->tm_isdst=tmp->tm_isdst;
22872287
}
22882288

‎src/backend/utils/adt/formatting.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.92 2005/07/21 03:56:16 momjian Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.93 2005/07/23 14:25:33 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -2989,7 +2989,7 @@ to_timestamp(PG_FUNCTION_ARGS)
29892989

29902990
do_to_timestamp(date_txt,fmt,&tm,&fsec);
29912991

2992-
tz=DetermineLocalTimeZone(&tm);
2992+
tz=DetermineTimeZoneOffset(&tm,global_timezone);
29932993

29942994
if (tm2timestamp(&tm,fsec,&tz,&result)!=0)
29952995
ereport(ERROR,

‎src/backend/utils/adt/nabstime.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.141 2005/07/22 19:55:50 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.142 2005/07/23 14:25:33 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -474,7 +474,7 @@ timestamp_abstime(PG_FUNCTION_ARGS)
474474
result=NOEND_ABSTIME;
475475
elseif (timestamp2tm(timestamp,NULL,tm,&fsec,NULL,NULL)==0)
476476
{
477-
tz=DetermineLocalTimeZone(tm);
477+
tz=DetermineTimeZoneOffset(tm,global_timezone);
478478
result=tm2abstime(tm,tz);
479479
}
480480
else

‎src/backend/utils/adt/timestamp.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.143 2005/07/2302:02:27 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.144 2005/07/2314:25:34 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2100,7 +2100,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
21002100
if (tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
21012101
tm->tm_mday= (day_tab[isleap(tm->tm_year)][tm->tm_mon-1]);
21022102

2103-
tz=DetermineLocalTimeZone(tm);
2103+
tz=DetermineTimeZoneOffset(tm,global_timezone);
21042104

21052105
if (tm2timestamp(tm,fsec,&tz,&timestamp)!=0)
21062106
ereport(ERROR,
@@ -2124,7 +2124,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
21242124
julian=date2j(tm->tm_year,tm->tm_mon,tm->tm_mday)+span->day;
21252125
j2date(julian,&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
21262126

2127-
tz=DetermineLocalTimeZone(tm);
2127+
tz=DetermineTimeZoneOffset(tm,global_timezone);
21282128

21292129
if (tm2timestamp(tm,fsec,&tz,&timestamp)!=0)
21302130
ereport(ERROR,
@@ -3104,7 +3104,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
31043104
}
31053105

31063106
if (redotz)
3107-
tz=DetermineLocalTimeZone(tm);
3107+
tz=DetermineTimeZoneOffset(tm,global_timezone);
31083108

31093109
if (tm2timestamp(tm,fsec,&tz,&result)!=0)
31103110
ereport(ERROR,
@@ -3529,7 +3529,7 @@ timestamp_part(PG_FUNCTION_ARGS)
35293529
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
35303530
errmsg("timestamp out of range")));
35313531

3532-
tz=DetermineLocalTimeZone(tm);
3532+
tz=DetermineTimeZoneOffset(tm,global_timezone);
35333533

35343534
if (tm2timestamp(tm,fsec,&tz,&timestamptz)!=0)
35353535
ereport(ERROR,
@@ -3924,12 +3924,11 @@ interval_part(PG_FUNCTION_ARGS)
39243924

39253925
/* timestamp_zone()
39263926
* Encode timestamp type with specified time zone.
3927-
* Returns timestamp with time zone, with the input
3928-
*rotated from local time to the specified zone.
3929-
*This function is tricky because instead of shifting
3930-
*the time _to_ a new time zone, it sets the time to _be_
3931-
*the specified timezone. This requires trickery
3932-
*of double-subtracting the requested timezone offset.
3927+
* This function is just timestamp2timestamptz() except instead of
3928+
*shifting to the global timezone, we shift to the specified timezone.
3929+
*This is different from the other AT TIME ZONE cases because instead
3930+
*of shifting to a _to_ a new time zone, it sets the time to _be_ the
3931+
*specified timezone.
39333932
*/
39343933
Datum
39353934
timestamp_zone(PG_FUNCTION_ARGS)
@@ -3943,11 +3942,12 @@ timestamp_zone(PG_FUNCTION_ARGS)
39433942
intlen;
39443943
structpg_tmtm;
39453944
fsec_tfsec;
3946-
3945+
boolfail;
3946+
39473947
if (TIMESTAMP_NOT_FINITE(timestamp))
39483948
PG_RETURN_TIMESTAMPTZ(timestamp);
39493949

3950-
/* Find the specified timezone? */
3950+
/* Find the specified timezone */
39513951
len= (VARSIZE(zone)-VARHDRSZ>TZ_STRLEN_MAX) ?
39523952
TZ_STRLEN_MAX :VARSIZE(zone)-VARHDRSZ;
39533953
memcpy(tzname,VARDATA(zone),len);
@@ -3963,17 +3963,20 @@ timestamp_zone(PG_FUNCTION_ARGS)
39633963
}
39643964

39653965
/* Apply the timezone change */
3966-
if (timestamp2tm(timestamp,&tz,&tm,&fsec,NULL,tzp)!=0||
3967-
tm2timestamp(&tm,fsec,&tz,&result)!=0)
3966+
fail= (timestamp2tm(timestamp,NULL,&tm,&fsec,NULL,tzp)!=0);
3967+
if (!fail)
3968+
{
3969+
tz=DetermineTimeZoneOffset(&tm,tzp);
3970+
fail= (tm2timestamp(&tm,fsec,&tz,&result)!=0);
3971+
}
3972+
if (fail)
39683973
{
39693974
ereport(ERROR,
39703975
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
39713976
errmsg("could not convert to time zone \"%s\"",
39723977
tzname)));
39733978
PG_RETURN_NULL();
39743979
}
3975-
/* Must double-adjust for timezone */
3976-
result=dt2local(result,-tz);
39773980

39783981
PG_RETURN_TIMESTAMPTZ(result);
39793982
}
@@ -4039,7 +4042,7 @@ timestamp2timestamptz(Timestamp timestamp)
40394042
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
40404043
errmsg("timestamp out of range")));
40414044

4042-
tz=DetermineLocalTimeZone(tm);
4045+
tz=DetermineTimeZoneOffset(tm,global_timezone);
40434046

40444047
if (tm2timestamp(tm,fsec,&tz,&result)!=0)
40454048
ereport(ERROR,

‎src/include/utils/datetime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
12-
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.55 2005/07/22 03:46:34 momjian Exp $
12+
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.56 2005/07/23 14:25:34 momjian Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -291,7 +291,7 @@ extern int DecodeInterval(char **field, int *ftype,
291291
externvoidDateTimeParseError(intdterr,constchar*str,
292292
constchar*datatype);
293293

294-
externintDetermineLocalTimeZone(structpg_tm*tm);
294+
externintDetermineTimeZoneOffset(structpg_tm*tm,pg_tz*tzp);
295295

296296
externintEncodeDateOnly(structpg_tm*tm,intstyle,char*str);
297297
externintEncodeTimeOnly(structpg_tm*tm,fsec_tfsec,int*tzp,intstyle,char*str);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp