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

Commit877f08d

Browse files
committed
Fix up timetz input so that a date is required only when the specified
timezone actually has a daylight-savings rule. This avoids breakingcases that used to work because they went through the DecodePosixTimezonecode path. Per contrib regression failures (mea culpa for not runningthose yesterday...). Also document the already-applied change to allowGMT offsets up to 14 hours.
1 parent723f716 commit877f08d

File tree

5 files changed

+77
-26
lines changed

5 files changed

+77
-26
lines changed

‎doc/src/sgml/datatype.sgml

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.178 2006/10/17 21:03:20 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.179 2006/10/18 16:43:13 tgl Exp $ -->
22

33
<chapter id="datatype">
44
<title id="datatype-title">Data Types</title>
@@ -1356,8 +1356,8 @@ SELECT b, char_length(b) FROM test2;
13561356
<entry><type>time [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
13571357
<entry>12 bytes</entry>
13581358
<entry>times of day only, with time zone</entry>
1359-
<entry>00:00:00+1359</entry>
1360-
<entry>24:00:00-1359</entry>
1359+
<entry>00:00:00+1459</entry>
1360+
<entry>24:00:00-1459</entry>
13611361
<entry>1 microsecond / 14 digits</entry>
13621362
</row>
13631363
</tbody>
@@ -1594,7 +1594,8 @@ SELECT b, char_length(b) FROM test2;
15941594
and <xref linkend="datatype-timezone-table">.) If a time zone is
15951595
specified in the input for <type>time without time zone</type>,
15961596
it is silently ignored. You can also specify a date but it will
1597-
be ignored, except when you use a full time zone name like
1597+
be ignored, except when you use a time zone name that involves a
1598+
daylight-savings rule, such as
15981599
<literal>America/New_York</literal>. In this case specifying the date
15991600
is required in order to determine whether standard or daylight-savings
16001601
time applies. The appropriate time zone offset is recorded in the
@@ -1747,12 +1748,7 @@ SELECT b, char_length(b) FROM test2;
17471748
</programlisting>
17481749

17491750
are valid values, which follow the <acronym>ISO</acronym> 8601
1750-
standard. You can also specify the full time zone name as in
1751-
<programlisting>
1752-
1999-01-08 04:05:06 America/New_York
1753-
</programlisting>
1754-
1755-
In addition, the wide-spread format
1751+
standard. In addition, the wide-spread format
17561752
<programlisting>
17571753
January 8 04:05:06 1999 PST
17581754
</programlisting>
@@ -2210,12 +2206,7 @@ January 8 04:05:06 1999 PST
22102206
There is a conceptual and practical difference between the abbreviations
22112207
and the full names: abbreviations always represent a fixed offset from
22122208
UTC, whereas most of the full names imply a local daylight-savings time
2213-
rule and so have two possible UTC offsets. That's why you always have to
2214-
specify a date if you want to use full time zone names in <type>timetz</>
2215-
values. This is also the reason why you should set <xref
2216-
linkend="guc-timezone"> to a full time zone name: this way,
2217-
<productname>PostgreSQL</productname>
2218-
will always know the correct UTC offset for your region.
2209+
rule and so have two possible UTC offsets.
22192210
</para>
22202211

22212212
<para>

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

Lines changed: 40 additions & 6 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.173 2006/10/17 21:03:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.174 2006/10/18 16:43:13 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1199,6 +1199,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
11991199
ptype=val;
12001200
break;
12011201

1202+
caseUNKNOWN_FIELD:
1203+
/*
1204+
* Before giving up and declaring error, check to see
1205+
* if it is an all-alpha timezone name.
1206+
*/
1207+
namedTz=pg_tzset(field[i]);
1208+
if (!namedTz)
1209+
returnDTERR_BAD_FORMAT;
1210+
/* we'll apply the zone setting below */
1211+
tmask=DTK_M(TZ);
1212+
break;
1213+
12021214
default:
12031215
returnDTERR_BAD_FORMAT;
12041216
}
@@ -1911,6 +1923,18 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
19111923
ptype=val;
19121924
break;
19131925

1926+
caseUNKNOWN_FIELD:
1927+
/*
1928+
* Before giving up and declaring error, check to see
1929+
* if it is an all-alpha timezone name.
1930+
*/
1931+
namedTz=pg_tzset(field[i]);
1932+
if (!namedTz)
1933+
returnDTERR_BAD_FORMAT;
1934+
/* we'll apply the zone setting below */
1935+
tmask=DTK_M(TZ);
1936+
break;
1937+
19141938
default:
19151939
returnDTERR_BAD_FORMAT;
19161940
}
@@ -1952,18 +1976,28 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
19521976

19531977
/*
19541978
* If we had a full timezone spec, compute the offset (we could not
1955-
* do it before, because we need the date to resolve DST status).
1979+
* do it before, because wemayneed the date to resolve DST status).
19561980
*/
19571981
if (namedTz!=NULL)
19581982
{
1959-
/* a date has to be specified */
1960-
if ((fmask&DTK_DATE_M)!=DTK_DATE_M)
1961-
returnDTERR_BAD_FORMAT;
1983+
longintgmtoff;
1984+
19621985
/* daylight savings time modifier disallowed with full TZ */
19631986
if (fmask&DTK_M(DTZMOD))
19641987
returnDTERR_BAD_FORMAT;
19651988

1966-
*tzp=DetermineTimeZoneOffset(tm,namedTz);
1989+
/* if non-DST zone, we do not need to know the date */
1990+
if (pg_get_timezone_offset(namedTz,&gmtoff))
1991+
{
1992+
*tzp=-(int)gmtoff;
1993+
}
1994+
else
1995+
{
1996+
/* a date has to be specified */
1997+
if ((fmask&DTK_DATE_M)!=DTK_DATE_M)
1998+
returnDTERR_BAD_FORMAT;
1999+
*tzp=DetermineTimeZoneOffset(tm,namedTz);
2000+
}
19672001
}
19682002

19692003
/* timezone not specified? then find local timezone if possible */

‎src/include/pgtime.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/include/pgtime.h,v 1.13 2006/09/16 20:14:33 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/pgtime.h,v 1.14 2006/10/18 16:43:14 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -55,6 +55,7 @@ extern size_t pg_strftime(char *s, size_t max, const char *format,
5555
externvoidpg_timezone_initialize(void);
5656
externpg_tz*pg_tzset(constchar*tzname);
5757
externbooltz_acceptable(pg_tz*tz);
58+
externboolpg_get_timezone_offset(constpg_tz*tz,longint*gmtoff);
5859
externconstchar*pg_get_timezone_name(pg_tz*tz);
5960

6061
externpg_tzenum*pg_tzenumerate_start(void);

‎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-2006, 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.61 2006/09/16 20:14:33 tgl Exp $
12+
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.62 2006/10/18 16:43:14 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -176,7 +176,7 @@
176176
#defineDTK_DATE_M(DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
177177
#defineDTK_TIME_M(DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
178178

179-
#defineMAXDATELEN51/* maximum possible length of an input date
179+
#defineMAXDATELEN63/* maximum possible length of an input date
180180
* string (not counting tr. null) */
181181
#defineMAXDATEFIELDS25/* maximum possible number of fields in a date
182182
* string */

‎src/timezone/localtime.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.15 2006/10/16 19:58:26 tgl Exp $
6+
* $PostgreSQL: pgsql/src/timezone/localtime.c,v 1.16 2006/10/18 16:43:14 tgl Exp $
77
*/
88

99
/*
@@ -1066,6 +1066,31 @@ pg_next_dst_boundary(const pg_time_t *timep,
10661066
return1;
10671067
}
10681068

1069+
/*
1070+
* If the given timezone uses only one GMT offset, store that offset
1071+
* into *gmtoff and return TRUE, else return FALSE.
1072+
*/
1073+
bool
1074+
pg_get_timezone_offset(constpg_tz*tz,longint*gmtoff)
1075+
{
1076+
/*
1077+
* The zone could have more than one ttinfo, if it's historically used
1078+
* more than one abbreviation. We return TRUE as long as they all have
1079+
* the same gmtoff.
1080+
*/
1081+
conststructstate*sp;
1082+
inti;
1083+
1084+
sp=&tz->state;
1085+
for (i=1;i<sp->typecnt;i++)
1086+
{
1087+
if (sp->ttis[i].tt_gmtoff!=sp->ttis[0].tt_gmtoff)
1088+
return false;
1089+
}
1090+
*gmtoff=sp->ttis[0].tt_gmtoff;
1091+
return true;
1092+
}
1093+
10691094
/*
10701095
* Return the name of the current timezone
10711096
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp