From 860c4a27bd571d2cb45c3d6639c21ab2cb429a10 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:10:25 +0300 Subject: [PATCH 1/6] Fix for weird timezones --- base/common/DateLUTImpl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base/common/DateLUTImpl.h b/base/common/DateLUTImpl.h index ec32d62bcad..a4d4c700d37 100644 --- a/base/common/DateLUTImpl.h +++ b/base/common/DateLUTImpl.h @@ -95,14 +95,14 @@ private: /// UTC offset is from -12 to +14 in all known time zones. This requires checking only three indices. - if ((guess == 0 || t >= lut[guess].date) && t < lut[DayNum(guess + 1)].date) + if (t >= lut[guess].date && t < lut[DayNum(guess + 1)].date) return guess; /// Time zones that have offset 0 from UTC do daylight saving time change (if any) towards increasing UTC offset (example: British Standard Time). - if (offset_at_start_of_epoch >= 0) - return DayNum(guess + 1); + if (t < lut[guess].date) + return DayNum(guess - 1); - return DayNum(guess - 1); + return DayNum(guess + 1); } inline const Values & find(time_t t) const @@ -579,7 +579,7 @@ public: return t / 3600; /// Assume that if offset was fractional, then the fraction is the same as at the beginning of epoch. - /// NOTE This assumption is false for "Pacific/Pitcairn" time zone. + /// NOTE This assumption is false for "Pacific/Pitcairn" and "Pacific/Kiritimati" time zones. return (t + 86400 - offset_at_start_of_epoch) / 3600; } From 1d559b9308148328c79a0f1e772e48ba9b93f654 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:21:20 +0300 Subject: [PATCH 2/6] Added a test --- tests/queries/0_stateless/01252_weird_time_zone.reference | 7 +++++++ tests/queries/0_stateless/01252_weird_time_zone.sql | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/queries/0_stateless/01252_weird_time_zone.reference create mode 100644 tests/queries/0_stateless/01252_weird_time_zone.sql diff --git a/tests/queries/0_stateless/01252_weird_time_zone.reference b/tests/queries/0_stateless/01252_weird_time_zone.reference new file mode 100644 index 00000000000..7d569731109 --- /dev/null +++ b/tests/queries/0_stateless/01252_weird_time_zone.reference @@ -0,0 +1,7 @@ +2020-01-02 03:04:05 +2020-01-02 03:04:05 +2020-01-02 03:04:05 +2020-01-02 03:04:05 +2020-01-02 03:04:05 +2020-01-02 03:04:05 +2020-01-02 03:04:05 diff --git a/tests/queries/0_stateless/01252_weird_time_zone.sql b/tests/queries/0_stateless/01252_weird_time_zone.sql new file mode 100644 index 00000000000..e2500548530 --- /dev/null +++ b/tests/queries/0_stateless/01252_weird_time_zone.sql @@ -0,0 +1,7 @@ +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kiritimati'); +SELECT toDateTime('2020-01-02 03:04:05', 'Africa/El_Aaiun'); +SELECT toDateTime('2020-01-02 03:04:05', 'Asia/Pyongyang'); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kwajalein'); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Apia'); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Enderbury'); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Fakaofo'); From ac31d22572faefaa85ac90fc949d80dcd675f8a2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:23:17 +0300 Subject: [PATCH 3/6] More tests --- .../0_stateless/01252_weird_time_zone.reference | 14 +++++++------- .../queries/0_stateless/01252_weird_time_zone.sql | 15 ++++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/queries/0_stateless/01252_weird_time_zone.reference b/tests/queries/0_stateless/01252_weird_time_zone.reference index 7d569731109..f2968d4efa6 100644 --- a/tests/queries/0_stateless/01252_weird_time_zone.reference +++ b/tests/queries/0_stateless/01252_weird_time_zone.reference @@ -1,7 +1,7 @@ -2020-01-02 03:04:05 -2020-01-02 03:04:05 -2020-01-02 03:04:05 -2020-01-02 03:04:05 -2020-01-02 03:04:05 -2020-01-02 03:04:05 -2020-01-02 03:04:05 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 +2020-01-02 03:04:05 2020-01-02 00:00:00 3 diff --git a/tests/queries/0_stateless/01252_weird_time_zone.sql b/tests/queries/0_stateless/01252_weird_time_zone.sql index e2500548530..cd01ca6832e 100644 --- a/tests/queries/0_stateless/01252_weird_time_zone.sql +++ b/tests/queries/0_stateless/01252_weird_time_zone.sql @@ -1,7 +1,8 @@ -SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kiritimati'); -SELECT toDateTime('2020-01-02 03:04:05', 'Africa/El_Aaiun'); -SELECT toDateTime('2020-01-02 03:04:05', 'Asia/Pyongyang'); -SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kwajalein'); -SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Apia'); -SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Enderbury'); -SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Fakaofo'); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kiritimati') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Africa/El_Aaiun') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Asia/Pyongyang') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Kwajalein') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Apia') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Enderbury') AS x, toStartOfDay(x), toHour(x); +SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Fakaofo') AS x, toStartOfDay(x), toHour(x); + From 48d6eb719a6133253553c35c2916bd5f5620d471 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:41:03 +0300 Subject: [PATCH 4/6] Fix error --- base/common/DateLUTImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/common/DateLUTImpl.h b/base/common/DateLUTImpl.h index a4d4c700d37..45637199e4f 100644 --- a/base/common/DateLUTImpl.h +++ b/base/common/DateLUTImpl.h @@ -95,7 +95,7 @@ private: /// UTC offset is from -12 to +14 in all known time zones. This requires checking only three indices. - if (t >= lut[guess].date && t < lut[DayNum(guess + 1)].date) + if ((guess == 0 || t >= lut[guess].date) && t < lut[DayNum(guess + 1)].date) return guess; /// Time zones that have offset 0 from UTC do daylight saving time change (if any) towards increasing UTC offset (example: British Standard Time). From 5a56714b6eeab64e2964da50da92566e1825a321 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:41:26 +0300 Subject: [PATCH 5/6] Added a test --- tests/queries/0_stateless/01252_weird_time_zone.sql | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/queries/0_stateless/01252_weird_time_zone.sql b/tests/queries/0_stateless/01252_weird_time_zone.sql index cd01ca6832e..68ea903a797 100644 --- a/tests/queries/0_stateless/01252_weird_time_zone.sql +++ b/tests/queries/0_stateless/01252_weird_time_zone.sql @@ -6,3 +6,10 @@ SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Apia') AS x, toStartOfDay(x), SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Enderbury') AS x, toStartOfDay(x), toHour(x); SELECT toDateTime('2020-01-02 03:04:05', 'Pacific/Fakaofo') AS x, toStartOfDay(x), toHour(x); +SELECT toHour(toDateTime(rand(), 'Pacific/Kiritimati') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Africa/El_Aaiun') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Asia/Pyongyang') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Pacific/Kwajalein') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Pacific/Apia') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Pacific/Enderbury') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; +SELECT toHour(toDateTime(rand(), 'Pacific/Fakaofo') AS t) AS h, t FROM numbers(1000000) WHERE h < 0 OR h > 23 ORDER BY h LIMIT 1 BY h; From 09dedaeac39def693be54a40274bc856d2bef85e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 20 Apr 2020 10:49:00 +0300 Subject: [PATCH 6/6] Fix error --- base/common/DateLUTImpl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/common/DateLUTImpl.h b/base/common/DateLUTImpl.h index 45637199e4f..cb41d2ef1c1 100644 --- a/base/common/DateLUTImpl.h +++ b/base/common/DateLUTImpl.h @@ -99,10 +99,10 @@ private: return guess; /// Time zones that have offset 0 from UTC do daylight saving time change (if any) towards increasing UTC offset (example: British Standard Time). - if (t < lut[guess].date) - return DayNum(guess - 1); + if (t >= lut[DayNum(guess + 1)].date) + return DayNum(guess + 1); - return DayNum(guess + 1); + return DayNum(guess - 1); } inline const Values & find(time_t t) const