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

Commit870a980

Browse files
committed
Support timezone abbreviations that sometimes change.
Up to now, PG has assumed that any given timezone abbreviation (such as"EDT") represents a constant GMT offset in the usage of any particularregion; we had a way to configure what that offset was, but not for itto be changeable over time. But, as with most things horological, thisview of the world is too simplistic: there are numerous regions that haveat one time or another switched to a different GMT offset but kept usingthe same timezone abbreviation. Almost the entire Russian Federation didthat a few years ago, and later this month they're going to do it again.And there are similar examples all over the world.To cope with this, invent the notion of a "dynamic timezone abbreviation",which is one that is referenced to a particular underlying timezone(as defined in the IANA timezone database) and means whatever it currentlymeans in that zone. For zones that use or have used daylight-savings time,the standard and DST abbreviations continue to have the property that youcan specify standard or DST time and get that time offset whether or notDST was theoretically in effect at the time. However, the abbreviationsmean what they meant at the time in question (or most recently before thattime) rather than being absolutely fixed.The standard abbreviation-list files have been changed to use this behaviorfor abbreviations that have actually varied in meaning since 1970. Theold simple-numeric definitions are kept for abbreviations that have notchanged, since they are a bit faster to resolve.While this is clearly a new feature, it seems necessary to back-patch itinto all active branches, because otherwise use of Russian zoneabbreviations is going to become even more problematic than it already was.This change supersedes the changes in commit513d06d et al to modify thefixed meanings of the Russian abbreviations; since we've not shipped thatyet, this will avoid an undesirably incompatible (not to mention incorrect)change in behavior for timestamps between 2011 and 2014.This patch makes some cosmetic changes in ecpglib to keep its usage ofdatetime lookup tables as similar as possible to the backend code, butdoesn't do anything about the increasingly obsolete set of timezoneabbreviation definitions that are hard-wired into ecpglib. Whatever wedo about that will likely not be appropriate material for back-patching.Also, a potential free() of a garbage pointer after an out-of-memoryfailure in ecpglib has been fixed.This patch also fixes pre-existing bugs in DetermineTimeZoneOffset() thatcaused it to produce unexpected results near a timezone transition, ifboth the "before" and "after" states are marked as standard time. We'donly ever thought about or tested transitions between standard and DSTtime, but that's not what's happening when a zone simply redefines theirbase GMT offset.In passing, update the SGML documentation to refer to the Olson/zoneinfo/zic timezone database as the "IANA" database, since it's now beingmaintained under the auspices of IANA.
1 parent4487b85 commit870a980

File tree

28 files changed

+2036
-668
lines changed

28 files changed

+2036
-668
lines changed

‎contrib/btree_gist/btree_ts.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -129,27 +129,11 @@ static const gbtree_ninfo tinfo =
129129
**************************************************/
130130

131131

132-
staticTimestamp
132+
staticinlineTimestamp
133133
tstz_to_ts_gmt(TimestampTzts)
134134
{
135-
Timestampgmt;
136-
intval,
137-
tz;
138-
139-
gmt=ts;
140-
DecodeSpecial(0,"gmt",&val);
141-
142-
if (ts<DT_NOEND&&ts>DT_NOBEGIN)
143-
{
144-
tz=val*60;
145-
146-
#ifdefHAVE_INT64_TIMESTAMP
147-
gmt-= (tz*INT64CONST(1000000));
148-
#else
149-
gmt-=tz;
150-
#endif
151-
}
152-
returngmt;
135+
/* No timezone correction is needed, since GMT is offset 0 by definition */
136+
return (Timestamp)ts;
153137
}
154138

155139

‎doc/src/sgml/config.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4716,9 +4716,9 @@ SET XML OPTION { DOCUMENT | CONTENT };
47164716
Sets the collection of time zone abbreviations that will be accepted
47174717
by the server for datetime input. The default is <literal>'Default'</>,
47184718
which is a collection that works in most of the world; there are
4719-
also 'Australia' and 'India', and other collections can be defined
4720-
for a particular installation. See <xref
4721-
linkend="datetime-appendix"> for more information.
4719+
also<literal>'Australia'</literal> and<literal>'India'</literal>,
4720+
and other collections can be definedfor a particular installation.
4721+
See <xreflinkend="datetime-config-files"> for more information.
47224722
</para>
47234723
</listitem>
47244724
</varlistentry>

‎doc/src/sgml/datatype.sgml

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,7 +2243,7 @@ January 8 04:05:06 1999 PST
22432243
but continue to be prone to arbitrary changes, particularly with
22442244
respect to daylight-savings rules.
22452245
<productname>PostgreSQL</productname> uses the widely-used
2246-
<literal>zoneinfo</> time zone database for information about
2246+
IANA (Olson) time zone database for information about
22472247
historical time zone rules. For times in the future, the assumption
22482248
is that the latest known rules for a given time zone will
22492249
continue to be observed indefinitely far into the future.
@@ -2308,8 +2308,8 @@ January 8 04:05:06 1999 PST
23082308
The recognized time zone names are listed in the
23092309
<literal>pg_timezone_names</literal> view (see <xref
23102310
linkend="view-pg-timezone-names">).
2311-
<productname>PostgreSQL</productname> uses the widely-used
2312-
<literal>zoneinfo</>time zone data for this purpose, so the same
2311+
<productname>PostgreSQL</productname> uses the widely-used IANA
2312+
time zone data for this purpose, so the same time zone
23132313
names are also recognized by much other software.
23142314
</para>
23152315
</listitem>
@@ -2342,7 +2342,7 @@ January 8 04:05:06 1999 PST
23422342
be functionally equivalent to United States East Coast time. When a
23432343
daylight-savings zone name is present, it is assumed to be used
23442344
according to the same daylight-savings transition rules used in the
2345-
<literal>zoneinfo</> time zone database's <filename>posixrules</> entry.
2345+
IANA time zone database's <filename>posixrules</> entry.
23462346
In a standard <productname>PostgreSQL</productname> installation,
23472347
<filename>posixrules</> is the same as <literal>US/Eastern</>, so
23482348
that POSIX-style time zone specifications follow USA daylight-savings
@@ -2353,9 +2353,25 @@ January 8 04:05:06 1999 PST
23532353
</itemizedlist>
23542354

23552355
In short, this is the difference between abbreviations
2356-
and full names: abbreviations always represent a fixed offset from
2357-
UTC, whereas most of the full names imply a local daylight-savings time
2358-
rule, and so have two possible UTC offsets.
2356+
and full names: abbreviations represent a specific offset from UTC,
2357+
whereas many of the full names imply a local daylight-savings time
2358+
rule, and so have two possible UTC offsets. As an example,
2359+
<literal>2014-06-04 12:00 America/New_York</> represents noon local
2360+
time in New York, which for this particular date was Eastern Daylight
2361+
Time (UTC-4). So <literal>2014-06-04 12:00 EDT</> specifies that
2362+
same time instant. But <literal>2014-06-04 12:00 EST</> specifies
2363+
noon Eastern Standard Time (UTC-5), regardless of whether daylight
2364+
savings was nominally in effect on that date.
2365+
</para>
2366+
2367+
<para>
2368+
To complicate matters, some jurisdictions have used the same timezone
2369+
abbreviation to mean different UTC offsets at different times; for
2370+
example, in Moscow <literal>MSK</> has meant UTC+3 in some years and
2371+
UTC+4 in others. <application>PostgreSQL</> interprets such
2372+
abbreviations according to whatever they meant (or had most recently
2373+
meant) on the specified date; but, as with the <literal>EST</> example
2374+
above, this is not necessarily the same as local civil time on that date.
23592375
</para>
23602376

23612377
<para>
@@ -2372,13 +2388,14 @@ January 8 04:05:06 1999 PST
23722388
</para>
23732389

23742390
<para>
2375-
In all cases, timezone names are recognized case-insensitively.
2376-
(This is a change from <productname>PostgreSQL</productname> versions
2377-
prior to 8.2, which were case-sensitive in some contexts but not others.)
2391+
In all cases, timezone names and abbreviations are recognized
2392+
case-insensitively. (This is a change from <productname>PostgreSQL</>
2393+
versions prior to 8.2, which were case-sensitive in some contexts but
2394+
not others.)
23782395
</para>
23792396

23802397
<para>
2381-
Neitherfull names nor abbreviations are hard-wired into the server;
2398+
Neithertimezone names nor abbreviations are hard-wired into the server;
23822399
they are obtained from configuration files stored under
23832400
<filename>.../share/timezone/</> and <filename>.../share/timezonesets/</>
23842401
of the installation directory

‎doc/src/sgml/datetime.sgml

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -374,22 +374,27 @@
374374
these formats:
375375

376376
<synopsis>
377-
<replaceable>time_zone_name</replaceable> <replaceable>offset</replaceable>
378-
<replaceable>time_zone_name</replaceable> <replaceable>offset</replaceable> D
377+
<replaceable>zone_abbreviation</replaceable> <replaceable>offset</replaceable>
378+
<replaceable>zone_abbreviation</replaceable> <replaceable>offset</replaceable> D
379+
<replaceable>zone_abbreviation</replaceable> <replaceable>time_zone_name</replaceable>
379380
@INCLUDE <replaceable>file_name</replaceable>
380381
@OVERRIDE
381382
</synopsis>
382383
</para>
383384

384385
<para>
385-
A <replaceable>time_zone_name</replaceable> is just the abbreviation
386-
being defined. The <replaceable>offset</replaceable> is thezone's
386+
A <replaceable>zone_abbreviation</replaceable> is just the abbreviation
387+
being defined. The <replaceable>offset</replaceable> is theequivalent
387388
offset in seconds from UTC, positive being east from Greenwich and
388389
negative being west. For example, -18000 would be five hours west
389390
of Greenwich, or North American east coast standard time. <literal>D</>
390-
indicates that the zone name represents local daylight-savings time
391-
rather than standard time. Since all known time zone offsets are on
392-
15 minute boundaries, the number of seconds has to be a multiple of 900.
391+
indicates that the zone name represents local daylight-savings time rather
392+
than standard time. Alternatively, a <replaceable>time_zone_name</> can
393+
be given, in which case that time zone definition is consulted, and the
394+
abbreviation's meaning in that zone is used. This alternative is
395+
recommended only for abbreviations whose meaning has historically varied,
396+
as looking up the meaning is noticeably more expensive than just using
397+
a fixed integer value.
393398
</para>
394399

395400
<para>
@@ -400,24 +405,24 @@
400405

401406
<para>
402407
The <literal>@OVERRIDE</> syntax indicates that subsequent entries in the
403-
file can override previous entries (i.e., entries obtained from included
404-
files). Without this, conflicting definitions of the same timezone
405-
abbreviation are considered an error.
408+
file can override previous entries (typically, entries obtained from
409+
includedfiles). Without this, conflicting definitions of the same
410+
timezoneabbreviation are considered an error.
406411
</para>
407412

408413
<para>
409414
In an unmodified installation, the file <filename>Default</> contains
410415
all the non-conflicting time zone abbreviations for most of the world.
411416
Additional files <filename>Australia</> and <filename>India</> are
412417
provided for those regions: these files first include the
413-
<literal>Default</> file and then add or modifytimezones as needed.
418+
<literal>Default</> file and then add or modifyabbreviations as needed.
414419
</para>
415420

416421
<para>
417422
For reference purposes, a standard installation also contains files
418423
<filename>Africa.txt</>, <filename>America.txt</>, etc, containing
419424
information about every time zone abbreviation known to be in use
420-
according to the<literal>zoneinfo</> timezone database. The zone name
425+
according to theIANA timezone database. The zone name
421426
definitions found in these files can be copied and pasted into a custom
422427
configuration file as needed. Note that these files cannot be directly
423428
referenced as <literal>timezone_abbreviations</> settings, because of
@@ -426,9 +431,9 @@
426431

427432
<note>
428433
<para>
429-
If an error occurs while reading the time zonedata sets, no new value is
430-
appliedbut the old set is kept. If the error occurs while starting the
431-
database, startup fails.
434+
If an error occurs while reading the time zoneabbreviation set, no new
435+
value isappliedand the old set is kept. If the error occurs while
436+
starting thedatabase, startup fails.
432437
</para>
433438
</note>
434439

‎doc/src/sgml/installation.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ su - postgres
12071207
<para>
12081208
<productname>PostgreSQL</> includes its own time zone database,
12091209
which it requires for date and time operations. This time zone
1210-
database is in fact compatible with the<quote>zoneinfo</> time zone
1210+
database is in fact compatible with theIANA time zone
12111211
database provided by many operating systems such as FreeBSD,
12121212
Linux, and Solaris, so it would be redundant to install it again.
12131213
When this option is used, the system-supplied time zone database

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

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,24 +2596,39 @@ timetz_zone(PG_FUNCTION_ARGS)
25962596
pg_tz*tzp;
25972597

25982598
/*
2599-
* Look up the requested timezone. First we look in thedate token table
2600-
* (to handle cases like "EST"), and if that fails, we look in the
2601-
* timezone database (to handle cases like "America/New_York"). (This
2602-
* matches the order in which timestamp input checks the cases; it's
2603-
* important because the timezone database unwisely uses a few zone names
2604-
* that are identical to offset abbreviations.)
2599+
* Look up the requested timezone. First we look in thetimezone
2600+
*abbreviation table(to handle cases like "EST"), and if that fails, we
2601+
*look in thetimezone database (to handle cases like
2602+
*"America/New_York"). (Thismatches the order in which timestamp input
2603+
*checks the cases; it'simportant because the timezone database unwisely
2604+
*uses a few zone namesthat are identical to offset abbreviations.)
26052605
*/
26062606
text_to_cstring_buffer(zone,tzname,sizeof(tzname));
2607+
2608+
/* DecodeTimezoneAbbrev requires lowercase input */
26072609
lowzone=downcase_truncate_identifier(tzname,
26082610
strlen(tzname),
26092611
false);
26102612

2611-
type=DecodeSpecial(0,lowzone,&val);
2613+
type=DecodeTimezoneAbbrev(0,lowzone,&val,&tzp);
26122614

26132615
if (type==TZ||type==DTZ)
2614-
tz=val*60;
2616+
{
2617+
/* fixed-offset abbreviation */
2618+
tz=-val;
2619+
}
2620+
elseif (type==DYNTZ)
2621+
{
2622+
/* dynamic-offset abbreviation, resolve using current time */
2623+
pg_time_tnow= (pg_time_t)time(NULL);
2624+
structpg_tm*tm;
2625+
2626+
tm=pg_localtime(&now,tzp);
2627+
tz=DetermineTimeZoneAbbrevOffset(tm,tzname,tzp);
2628+
}
26152629
else
26162630
{
2631+
/* try it as a full zone name */
26172632
tzp=pg_tzset(tzname);
26182633
if (tzp)
26192634
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp