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?
'+02:00'. I added some more. – Erwin Brandstetter Aug 27 '18 at 04:10'+02:00'is treated as POSIX, but why is'PST8PDT'treated as ISO (yielding negative, west-of-Greenwich offset-07:00:00), and most importantly, why is-7treated as ISO, too, despite docs saying numbers are treated as POSIX (see my addendum from yesterday)? Or does the "Timezone settings given as numbers or intervals are internally translated to POSIX timezone syntax" only refer to output ofSHOW TIME ZONE, and not how they are parsed/interpreted in the first place? – dwelle Aug 27 '18 at 08:20