B.5. Указание часовых поясов в стиле POSIX
Postgres Pro может воспринимать указание часового пояса, записанное по правилам стандарта POSIX, в соответствии с которыми, в частности, задаётся переменная окружения TZ. Указания часовых поясов в стиле POSIX не удовлетворяют всем условиям, продиктованным сложной историей часовых поясов в реальном мире, но иногда использование этих указаний бывает оправданным.
Указание часового пояса в стиле POSIX выглядит так:
STDсмещение[DST[смещение_летнего_времени] [ ,правило] ]
(Для наглядности между полями добавлены пробелы, но в реальном указании их не должно быть.) В нём содержатся следующие поля:
STD— аббревиатура, используемая для стандартного часового пояса.смещение— стандартное смещение пояса от UTC.DST— аббревиатура часового пояса при переходе на летнее время. Если это поле и следующие за ним опущены, для часового пояса будет использоваться фиксированное смещение от UTC без учёта перехода на летнее время.смещение_летнего_времени— смещение часового пояса от UTC при переходе на летнее время. Это поле обычно опускается, так как по умолчанию это смещение равно стандартномусмещениюминус один час, что практически всегда имеет место на практике.правило— определяет, как должен учитываться переход на летнее время, в соответствии с представленным ниже описанием.
В этой записи аббревиатура часового пояса может задаваться набором букв, например EST, или произвольной строкой, заключённой в угловые скобки, например <UTC-05>. Заметьте, что показанные здесь аббревиатуры используются только при выводе и только в некоторых выходных форматах. Распознаваемые во входных значениях даты/времени аббревиатуры часовых поясов описаны в Разделе B.4.
В полях смещений задаётся сдвиг от UTC в часах и, возможно, минутах и секундах. Они имеют формат чч[:мм[:сс]] и могут содержать спереди знак (+ или -). Положительный знак имеют часовые пояса к западу от Гринвича. (Заметьте, что это противоположно соглашению ISO-8601, используемому в других областях Postgres Pro.) Компонент чч может содержать одну или две цифры, а мм и сс (если они задаются) должны состоять ровно из двух цифр.
Поле, задающее правило перехода на летнее время, имеет следующий формат:
дата_перехода[/время_перехода],дата_возврата[/время_возврата]
(Как и ранее, реальное указание не должно содержать пробелы.) Поля дата_перехода и время_перехода определяют момент перехода на летнее время, а поля дата_возврата и время_возврата определяют дату возврата к поясному времени. (В некоторых регионах, в частности, в Южном полушарии, вторая дата в календаре может предшествовать первой.) Даты могут задаваться в одном из следующих форматов:
nПростое целое, обозначающее день года, с нумерацией от нуля до 364, или 365 в високосном году.
JnВ этой записи
nобозначает номер дня от 1 до 365, а 29 февраля пропускается, даже когда фактически присутствует. (Таким образом, смены часового пояса, происходящие 29 февраля, в этой записи выразить нельзя. Однако после февраля дни имеют одинаковые номера и в обычные, и в високосные годы, так что эта запись обычно полезнее тем, что позволяет выразить одним числом фиксированную дату перевода часов.)Mm.n.dЭта форма задаёт дату перехода, которая всегда назначается в определённый месяц и день недели. Здесь
mобозначает номер месяца от 1 до 12, аn— номер повторения в этом месяце дня недели, заданного полемd. В качествеnможет задаваться число от 1 до 4 либо число 5, выбирающее последнюю дату с заданным днём недели в этом месяце (она может быть фактически четвёртой или пятой). В качествеdзадаётся число от 0 до 6, обозначающее день недели (0 — воскресенье). Например, записьM3.2.0расшифровывается как «второе воскресенье марта».
Примечание
Для описания многих существующих правил перехода на летнее время обычно достаточно формата M. Но заметьте, что ни одна из этих вариаций не позволяет описать изменения правил перевода часов. Поэтому на практике для правильной интерпретации значений времени, относящихся к прошлому, необходимы исторические данные, хранящиеся в привязке к именованным часовым поясам (в базе данных IANA с информацией о часовых поясах).
Поля времени в описании правила перехода имеют тот же формат, что и поля смещений, описанные ранее, за исключением того, что в них не может быть знака. Они определяют текущее местное время, в которое производится перевод часов. По умолчанию временем перевода часов считается 02:00:00.
Если задаётся аббревиатура для летнего времени, но правило перехода не задано, в качестве правила по умолчанию используется M3.2.0,M11.1.0, что соответствует существующему в США в 2020 г. порядку. То есть часы переводятся на летнее время во второе воскресенье марта, а на зимнее — в первое воскресенье ноября, в два часа по действующему времени. Заметьте, что это правило даёт правильные даты для США только с 2007 г.
Например, запись CET-1CEST,M3.5.0,M10.5.0/3 отражает действующую в 2020 г. практику перевода часов в Париже. Это указание говорит, что стандартное поясное время имеет аббревиатуру CET и оно смещено на час вперёд (к востоку) от UTC; летнее время имеет аббревиатуру CEST и смещено вперед от UTC на два часа (это определяется неявно). Часы переводятся на летнее время в последнее воскресенье марта в 2:00 CET, а на зимнее — в последнее воскресенье октября в 3:00 CEST.
Названия четырёх часовых поясов EST5EDT, CST6CDT, MST7MDT и PST8PDT выглядят как определяющие часовые пояса в стиле POSIX, но в реальности по историческим причинам они воспринимаются как имена часовых поясов, наравне с другими, так как в базе данных IANA есть файлы с такими именами. Практическое следствие этого состоит в том, что для данных имён может быть получена историческая информация о действовавших правилах перехода на летнее время в США, которую не может дать обычное указание в стиле POSIX.
Имейте в виду, что ошибиться в указании часового пояса в стиле POSIX очень легко, так как адекватность аббревиатуры никак не проверяется. Например, команда SET TIMEZONE TO FOOBAR0 выполнится без ошибки, и система в итоге будет использовать весьма своеобразную аббревиатуру для UTC.
B.5. POSIX Time Zone Specifications
Postgres Pro can accept time zone specifications that are written according to the POSIX standard's rules for the TZ environment variable. POSIX time zone specifications are inadequate to deal with the complexity of real-world time zone history, but there are sometimes reasons to use them.
A POSIX time zone specification has the form
STDoffset[DST[dstoffset] [ ,rule] ]
(For readability, we show spaces between the fields, but spaces should not be used in practice.) The fields are:
STDis the zone abbreviation to be used for standard time.offsetis the zone's standard-time offset from UTC.DSTis the zone abbreviation to be used for daylight-savings time. If this field and the following ones are omitted, the zone uses a fixed UTC offset with no daylight-savings rule.dstoffsetis the daylight-savings offset from UTC. This field is typically omitted, since it defaults to one hour less than the standard-timeoffset, which is usually the right thing.ruledefines the rule for when daylight savings is in effect, as described below.
In this syntax, a zone abbreviation can be a string of letters, such as EST, or an arbitrary string surrounded by angle brackets, such as <UTC-05>. Note that the zone abbreviations given here are only used for output, and even then only in some timestamp output formats. The zone abbreviations recognized in timestamp input are determined as explained in Section B.4.
The offset fields specify the hours, and optionally minutes and seconds, difference from UTC. They have the format hh[:mm[:ss]] optionally with a leading sign (+ or -). The positive sign is used for zones west of Greenwich. (Note that this is the opposite of the ISO-8601 sign convention used elsewhere in Postgres Pro.) hh can have one or two digits; mm and ss (if used) must have two.
The daylight-savings transition rule has the format
dstdate[/dsttime],stddate[/stdtime]
(As before, spaces should not be included in practice.) The dstdate and dsttime fields define when daylight-savings time starts, while stddate and stdtime define when standard time starts. (In some cases, notably in zones south of the equator, the former might be later in the year than the latter.) The date fields have one of these formats:
nA plain integer denotes a day of the year, counting from zero to 364, or to 365 in leap years.
JnIn this form,
ncounts from 1 to 365, and February 29 is not counted even if it is present. (Thus, a transition occurring on February 29 could not be specified this way. However, days after February have the same numbers whether it's a leap year or not, so that this form is usually more useful than the plain-integer form for transitions on fixed dates.)Mm.n.dThis form specifies a transition that always happens during the same month and on the same day of the week.
midentifies the month, from 1 to 12.nspecifies then'th occurrence of the weekday identified byd.nis a number between 1 and 4, or 5 meaning the last occurrence of that weekday in the month (which could be the fourth or the fifth).dis a number between 0 and 6, with 0 indicating Sunday. For example,M3.2.0means “the second Sunday in March”.
Note
The M format is sufficient to describe many common daylight-savings transition laws. But note that none of these variants can deal with daylight-savings law changes, so in practice the historical data stored for named time zones (in the IANA time zone database) is necessary to interpret past time stamps correctly.
The time fields in a transition rule have the same format as the offset fields described previously, except that they cannot contain signs. They define the current local time at which the change to the other time occurs. If omitted, they default to 02:00:00.
If a daylight-savings abbreviation is given but the transition rule field is omitted, the fallback behavior is to use the rule M3.2.0,M11.1.0, which corresponds to USA practice as of 2020 (that is, spring forward on the second Sunday of March, fall back on the first Sunday of November, both transitions occurring at 2AM prevailing time). Note that this rule does not give correct USA transition dates for years before 2007.
As an example, CET-1CEST,M3.5.0,M10.5.0/3 describes current (as of 2020) timekeeping practice in Paris. This specification says that standard time has the abbreviation CET and is one hour ahead (east) of UTC; daylight savings time has the abbreviation CEST and is implicitly two hours ahead of UTC; daylight savings time begins on the last Sunday in March at 2AM CET and ends on the last Sunday in October at 3AM CEST.
The four timezone names EST5EDT, CST6CDT, MST7MDT, and PST8PDT look like they are POSIX zone specifications. However, they actually are treated as named time zones because (for historical reasons) there are files by those names in the IANA time zone database. The practical implication of this is that these zone names will produce valid historical USA daylight-savings transitions, even when a plain POSIX specification would not.
One should be wary that it is easy to misspell a POSIX-style time zone specification, since there is no check on the reasonableness of the zone abbreviation(s). For example, SET TIMEZONE TO FOOBAR0 will work, leaving the system effectively using a rather peculiar abbreviation for UTC.