Setting time zone as numeric offset (without abbrev
, thus IMO not in POSIX format) is still interpreted by PostgreSQL as POSIX format:
SET TIME ZONE '+02:00';
At least I assume, because checking the UTF offset via:
SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec';
yields -02:00:00
, which means the offset from Greenwich is reversed as noted in docs:
Another issue to keep in mind is that in POSIX time zone names, positive offsets are used for locations west of Greenwich. Everywhere else, PostgreSQL follows the ISO-8601 convention that positive timezone offsets are east of Greenwich.
Setting via named time zone yields positive offset from UTC, which is correct:
SET TIME ZONE 'Europe/Prague'; -- +02:00 DST at time of writing
SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec'; -- `02:00:00`
Postgres docs state there are 3 ways to specify time zone, none of which mention the +00:00
numeric syntax:
PostgreSQL allows you to specify time zones in three different forms:
- A full time zone name, for example
America/New_York
. The recognized time zone names are listed in thepg_timezone_names
view (see Section 51.90). PostgreSQL uses the widely-used IANA time zone data for this purpose, so the same time zone names are also recognized by much other software.- A time zone abbreviation, for example
PST
. Such a specification merely defines a particular offset from UTC, in contrast to full time zone names which can imply a set of daylight savings transition-date rules as well. The recognized abbreviations are listed in thepg_timezone_abbrevs
view (see Section 51.89). You cannot set the configuration parameters TimeZone or log_timezone to a time zone abbreviation, but you can use abbreviations in date/time input values and with theAT TIME ZONE
operator.- In addition to the timezone names and abbreviations, PostgreSQL will accept POSIX-style time zone specifications of the form
STDoffset
orSTD
offset
DST
[...]
But since the POSIX (point 3 above) doesn't mention the ±00:00
format anywhere (only that it requires STD
abbrev), I assume it does not fall into that category.
Furthermore, elsewhere in the docs the ±00:00
is explicitly specified as ISO 8601
. Though I understand that applies to TIMESTAMPTZ
datatype, and not runtime timezone
configuration, it seems weird for postgres to interpret the same format in two different ways.
On top of that, the ±00:00
format is mentioned on wikipedia as ISO 8601.
Q1: So, does Postgres really interpret the ±00:00
as POSIX (or is there something else going on), and why?
Q2: Also, is there a definitive list of which formats that you can set either in postgresql.conf
or at runtime via SET TIME ZONE
are interpreted as POSIX, and which as ISO-8601?
(This question is a continuation of my previous: Why does postgresql differentiate between named and numeric time zone notations? Thanks jjanes for pointing me in the right direction.)
EDIT (18-08-26 18:56) to reflect Erwin's answer:
First, the SET
docs state (added list numbers, emphasis):
SET TIME ZONE value
is an alias forSET timezone TO value
. The syntaxSET TIME ZONE
allows special syntax for the time zone specification. Here are examples of valid values:
'PST8PDT'
The time zone for Berkeley, California.
'Europe/Rome'
The time zone for Italy.
-7
The time zone 7 hours west from UTC (equivalent to PDT). Positive values are east from UTC.
INTERVAL '-08:00' HOUR TO MINUTE
The time zone 8 hours west from UTC (equivalent to PST).
[...]
Timezone settings given as numbers or intervals are internally translated to POSIX timezone syntax. For example, after
SET TIME ZONE -7
,SHOW TIME ZONE
would report<-07>+07
.
The emphasized sentence is either wrong, incomplete, or else I don't understand it at all.
does it mean that their POSIX-ish string (1), it being a string, is interpreted as ISO-8601? Let's test that.
SET TIME ZONE 'PST8PDT'; SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec';
Yields
-07:00:00
, which is negative, and negative values are west of Greenwich only in ISO-8601, since the docs state (emphasis mine):Another issue to keep in mind is that in POSIX time zone names, positive offsets are used for locations west of Greenwich. Everywhere else, PostgreSQL follows the ISO-8601 convention that positive timezone offsets are east of Greenwich.
Unless that quote above still only applies timestamp literals.
If not, it seems that
'PST8PDT'
string is indeed interpreted as ISO-8601.But,
SET TIME ZONE 'UTC2'; SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec';
yields
-02:00:00
.. So are we back in POSIX again? Or isUTC2
not a POSIXSTDoffset
format?The number format
-7
is specified to be interpreted as POSIX, so let's test that again:SET TIME ZONE 2; SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec';
yields
02:00:00
. Hmm.. that sounds ISO-8601 enough to me. +2 hours, east of Greenwich.Where does
'+02:00'
fall into? It's not a number, not an interval, though it acts as if postgres parses it as interval, because it results in POSIX offsets:SET TIME ZONE '+02:00'; SELECT EXTRACT(TIMEZONE FROM now()) * interval '1sec';
Yields
-02:00:00
.
So I'm still confused. One other questions that comes to mind:
Q3: does west/east of Greenwich plus/minus reversal for POSIX apply just for timestamp literals, or time zone configuration, too?