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

Commit137e7c1

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 parent69e29b1 commit137e7c1

File tree

29 files changed

+2008
-653
lines changed

29 files changed

+2008
-653
lines changed

‎contrib/btree_gist/btree_ts.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -212,27 +212,11 @@ tstz_dist(PG_FUNCTION_ARGS)
212212
**************************************************/
213213

214214

215-
staticTimestamp
215+
staticinlineTimestamp
216216
tstz_to_ts_gmt(TimestampTzts)
217217
{
218-
Timestampgmt;
219-
intval,
220-
tz;
221-
222-
gmt=ts;
223-
DecodeSpecial(0,"gmt",&val);
224-
225-
if (ts<DT_NOEND&&ts>DT_NOBEGIN)
226-
{
227-
tz=val*60;
228-
229-
#ifdefHAVE_INT64_TIMESTAMP
230-
gmt-= (tz*INT64CONST(1000000));
231-
#else
232-
gmt-=tz;
233-
#endif
234-
}
235-
returngmt;
218+
/* No timezone correction is needed, since GMT is offset 0 by definition */
219+
return (Timestamp)ts;
236220
}
237221

238222

‎doc/src/sgml/config.sgml

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

‎doc/src/sgml/datatype.sgml

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,7 +2325,7 @@ January 8 04:05:06 1999 PST
23252325
but continue to be prone to arbitrary changes, particularly with
23262326
respect to daylight-savings rules.
23272327
<productname>PostgreSQL</productname> uses the widely-used
2328-
<literal>zoneinfo</> (Olson) time zone database for information about
2328+
IANA (Olson) time zone database for information about
23292329
historical time zone rules. For times in the future, the assumption
23302330
is that the latest known rules for a given time zone will
23312331
continue to be observed indefinitely far into the future.
@@ -2390,8 +2390,8 @@ January 8 04:05:06 1999 PST
23902390
The recognized time zone names are listed in the
23912391
<literal>pg_timezone_names</literal> view (see <xref
23922392
linkend="view-pg-timezone-names">).
2393-
<productname>PostgreSQL</productname> uses the widely-used
2394-
<literal>zoneinfo</>time zone data for this purpose, so the same
2393+
<productname>PostgreSQL</productname> uses the widely-used IANA
2394+
time zone data for this purpose, so the same time zone
23952395
names are also recognized by much other software.
23962396
</para>
23972397
</listitem>
@@ -2424,7 +2424,7 @@ January 8 04:05:06 1999 PST
24242424
be functionally equivalent to United States East Coast time. When a
24252425
daylight-savings zone name is present, it is assumed to be used
24262426
according to the same daylight-savings transition rules used in the
2427-
<literal>zoneinfo</> time zone database's <filename>posixrules</> entry.
2427+
IANA time zone database's <filename>posixrules</> entry.
24282428
In a standard <productname>PostgreSQL</productname> installation,
24292429
<filename>posixrules</> is the same as <literal>US/Eastern</>, so
24302430
that POSIX-style time zone specifications follow USA daylight-savings
@@ -2435,9 +2435,25 @@ January 8 04:05:06 1999 PST
24352435
</itemizedlist>
24362436

24372437
In short, this is the difference between abbreviations
2438-
and full names: abbreviations always represent a fixed offset from
2439-
UTC, whereas most of the full names imply a local daylight-savings time
2440-
rule, and so have two possible UTC offsets.
2438+
and full names: abbreviations represent a specific offset from UTC,
2439+
whereas many of the full names imply a local daylight-savings time
2440+
rule, and so have two possible UTC offsets. As an example,
2441+
<literal>2014-06-04 12:00 America/New_York</> represents noon local
2442+
time in New York, which for this particular date was Eastern Daylight
2443+
Time (UTC-4). So <literal>2014-06-04 12:00 EDT</> specifies that
2444+
same time instant. But <literal>2014-06-04 12:00 EST</> specifies
2445+
noon Eastern Standard Time (UTC-5), regardless of whether daylight
2446+
savings was nominally in effect on that date.
2447+
</para>
2448+
2449+
<para>
2450+
To complicate matters, some jurisdictions have used the same timezone
2451+
abbreviation to mean different UTC offsets at different times; for
2452+
example, in Moscow <literal>MSK</> has meant UTC+3 in some years and
2453+
UTC+4 in others. <application>PostgreSQL</> interprets such
2454+
abbreviations according to whatever they meant (or had most recently
2455+
meant) on the specified date; but, as with the <literal>EST</> example
2456+
above, this is not necessarily the same as local civil time on that date.
24412457
</para>
24422458

24432459
<para>
@@ -2454,13 +2470,14 @@ January 8 04:05:06 1999 PST
24542470
</para>
24552471

24562472
<para>
2457-
In all cases, timezone names are recognized case-insensitively.
2458-
(This is a change from <productname>PostgreSQL</productname> versions
2459-
prior to 8.2, which were case-sensitive in some contexts but not others.)
2473+
In all cases, timezone names and abbreviations are recognized
2474+
case-insensitively. (This is a change from <productname>PostgreSQL</>
2475+
versions prior to 8.2, which were case-sensitive in some contexts but
2476+
not others.)
24602477
</para>
24612478

24622479
<para>
2463-
Neitherfull names nor abbreviations are hard-wired into the server;
2480+
Neithertimezone names nor abbreviations are hard-wired into the server;
24642481
they are obtained from configuration files stored under
24652482
<filename>.../share/timezone/</> and <filename>.../share/timezonesets/</>
24662483
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 <varname>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
@@ -1079,7 +1079,7 @@ su - postgres
10791079
<para>
10801080
<productname>PostgreSQL</> includes its own time zone database,
10811081
which it requires for date and time operations. This time zone
1082-
database is in fact compatible with the<quote>zoneinfo</> time zone
1082+
database is in fact compatible with theIANA time zone
10831083
database provided by many operating systems such as FreeBSD,
10841084
Linux, and Solaris, so it would be redundant to install it again.
10851085
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
@@ -2627,24 +2627,39 @@ timetz_zone(PG_FUNCTION_ARGS)
26272627
pg_tz*tzp;
26282628

26292629
/*
2630-
* Look up the requested timezone. First we look in thedate token table
2631-
* (to handle cases like "EST"), and if that fails, we look in the
2632-
* timezone database (to handle cases like "America/New_York"). (This
2633-
* matches the order in which timestamp input checks the cases; it's
2634-
* important because the timezone database unwisely uses a few zone names
2635-
* that are identical to offset abbreviations.)
2630+
* Look up the requested timezone. First we look in thetimezone
2631+
*abbreviation table(to handle cases like "EST"), and if that fails, we
2632+
*look in thetimezone database (to handle cases like
2633+
*"America/New_York"). (Thismatches the order in which timestamp input
2634+
*checks the cases; it'simportant because the timezone database unwisely
2635+
*uses a few zone namesthat are identical to offset abbreviations.)
26362636
*/
26372637
text_to_cstring_buffer(zone,tzname,sizeof(tzname));
2638+
2639+
/* DecodeTimezoneAbbrev requires lowercase input */
26382640
lowzone=downcase_truncate_identifier(tzname,
26392641
strlen(tzname),
26402642
false);
26412643

2642-
type=DecodeSpecial(0,lowzone,&val);
2644+
type=DecodeTimezoneAbbrev(0,lowzone,&val,&tzp);
26432645

26442646
if (type==TZ||type==DTZ)
2645-
tz=val*MINS_PER_HOUR;
2647+
{
2648+
/* fixed-offset abbreviation */
2649+
tz=-val;
2650+
}
2651+
elseif (type==DYNTZ)
2652+
{
2653+
/* dynamic-offset abbreviation, resolve using current time */
2654+
pg_time_tnow= (pg_time_t)time(NULL);
2655+
structpg_tm*tm;
2656+
2657+
tm=pg_localtime(&now,tzp);
2658+
tz=DetermineTimeZoneAbbrevOffset(tm,tzname,tzp);
2659+
}
26462660
else
26472661
{
2662+
/* try it as a full zone name */
26482663
tzp=pg_tzset(tzname);
26492664
if (tzp)
26502665
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp