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_namesview (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_abbrevsview (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 ZONEoperator.- In addition to the timezone names and abbreviations, PostgreSQL will accept POSIX-style time zone specifications of the form
STDoffsetorSTDoffsetDST[...]
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 valueis an alias forSET timezone TO value. The syntaxSET TIME ZONEallows 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.
-7The time zone 7 hours west from UTC (equivalent to PDT). Positive values are east from UTC.
INTERVAL '-08:00' HOUR TO MINUTEThe 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 ZONEwould 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 isUTC2not a POSIXSTDoffsetformat?The number format
-7is 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?