From b22ca7648b6fafea51978d206a5989cfe0900211 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 19 Jun 2020 13:55:21 -0400 Subject: [PATCH] Future-proof regression tests against possibly-missing posixrules file. The IANA time zone folk have deprecated use of a "posixrules" file in the tz database. While for now it's our choice whether to keep supplying one in our own builds, installations built with --with-system-tzdata will soon be needing to cope with that file not being present, at least on some platforms. This causes a problem for the horology test, which expected the nonstandard POSIX zone spec "CST7CDT" to apply pre-2007 US daylight savings rules. That does happen if the posixrules file supplies such information, but otherwise the test produces undesired results. To fix, add an explicit transition date rule that matches 2005 practice. (We could alternatively have switched the test to use some real time zone, but it seems useful to have coverage of this type of zone spec.) While at it, update a documentation example that also relied on "CST7CDT"; use a real-world zone name instead. Also, document why the zone names EST5EDT, CST6CDT, MST7MDT, PST8PDT aren't subject to similar failures when "posixrules" is missing. Back-patch to all supported branches, since the hazard is the same for all. Discussion: https://postgr.es/m/1665379.1592581287@sss.pgh.pa.us --- doc/src/sgml/datetime.sgml | 12 ++++++++++++ doc/src/sgml/func.sgml | 22 +++++++++++++--------- src/test/regress/expected/horology.out | 3 ++- src/test/regress/sql/horology.sql | 3 ++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/datetime.sgml b/doc/src/sgml/datetime.sgml index a0cf4bab52..c35dee7e13 100644 --- a/doc/src/sgml/datetime.sgml +++ b/doc/src/sgml/datetime.sgml @@ -757,6 +757,18 @@ 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 due to + lack of a suitable posixrules file. + + 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 diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 4ad76b04b2..12a48f9926 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -7876,18 +7876,22 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS When adding an interval value to (or subtracting an interval value from) a timestamp with time zone value, the days component advances or decrements the date of the - timestamp with time zone by the indicated number of days. + timestamp with time zone by the indicated number of days, + keeping the time of day the same. Across daylight saving time changes (when the session time zone is set to a time zone that recognizes DST), this means interval '1 day' does not necessarily equal interval '24 hours'. - For example, with the session time zone set to CST7CDT, - timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' - will produce timestamp with time zone '2005-04-03 12:00-06', - while adding interval '24 hours' to the same initial - timestamp with time zone produces - timestamp with time zone '2005-04-03 13:00-06', as there is - a change in daylight saving time at 2005-04-03 02:00 in time zone - CST7CDT. + For example, with the session time zone set + to America/Denver: + +SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; +Result: 2005-04-03 12:00:00-06 +SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; +Result: 2005-04-03 13:00:00-06 + + This happens because an hour was skipped due to a change in daylight saving + time at 2005-04-03 02:00:00 in time zone + America/Denver. diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out index bbbe76b4c0..2e2e3790bb 100644 --- a/src/test/regress/expected/horology.out +++ b/src/test/regress/expected/horology.out @@ -652,7 +652,8 @@ SELECT (timestamp with time zone 'tomorrow' > 'now') as "True"; (1 row) -- timestamp with time zone, interval arithmetic around DST change -SET TIME ZONE 'CST7CDT'; +-- (just for fun, let's use an intentionally nonstandard POSIX zone spec) +SET TIME ZONE 'CST7CDT,M4.1.0,M10.5.0'; SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' as "Apr 3, 12:00"; Apr 3, 12:00 ------------------------------ diff --git a/src/test/regress/sql/horology.sql b/src/test/regress/sql/horology.sql index 90b9a8e90f..fbad8dea9f 100644 --- a/src/test/regress/sql/horology.sql +++ b/src/test/regress/sql/horology.sql @@ -122,7 +122,8 @@ SELECT (timestamp with time zone 'tomorrow' = (timestamp with time zone 'yesterd SELECT (timestamp with time zone 'tomorrow' > 'now') as "True"; -- timestamp with time zone, interval arithmetic around DST change -SET TIME ZONE 'CST7CDT'; +-- (just for fun, let's use an intentionally nonstandard POSIX zone spec) +SET TIME ZONE 'CST7CDT,M4.1.0,M10.5.0'; SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' as "Apr 3, 12:00"; SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '24 hours' as "Apr 3, 13:00"; SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '1 day' as "Apr 2, 12:00";