From 9121eccca9ca09ebc45e4ab3a67f9702750257d4 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov <sergeyb@tarantool.org> Date: Tue, 30 Jul 2024 14:57:01 +0300 Subject: [PATCH] datetime: support tz field in :totable() `datetime` module has a function `:totable()` that converts the information from a datetime object into the table format. The commit 43e10ed34949 ("build, lua: built-in module datetime") added `tzoffset` field to the datetime object and to table produced by `:totable()`. The commit 9ee45289e012 ("datetime: datetime.TZ array") added fields `tz` and `tzindex` to the datetime object, but not to the table produced by `:totable()`. The patch fixes that. Note, `tzindex` is not added, because it is an internal field. ``` tarantool> datetime.parse('2004-12-01T00:00 Europe/Moscow'):totable() --- - tz: Europe/Moscow sec: 0 min: 0 yday: 336 day: 1 nsec: 0 isdst: false wday: 4 tzoffset: 180 month: 12 year: 2004 hour: 0 ... ``` Fixes #10331 Follows up #6751 @TarantoolBot document Title: Support of tz field in :totable() In addition to the `tzoffset` in a table produced by `:totable` we added `tz` field. ``` tarantool> datetime.parse('2004-12-01T00:00 Europe/Moscow'):totable() --- - tz: Europe/Moscow sec: 0 min: 0 yday: 336 day: 1 nsec: 0 isdst: false wday: 4 tzoffset: 180 month: 12 year: 2004 hour: 0 ... ``` (cherry picked from commit 90552e55e0921405c43ea086ae418a72c9f000e4) --- .../unreleased/gh-10331-tz-in-totable.md | 4 ++ src/lua/datetime.lua | 1 + test/app-tap/datetime.test.lua | 54 +++++++++++++++++-- test/sql-luatest/datetime_test.lua | 6 ++- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/gh-10331-tz-in-totable.md diff --git a/changelogs/unreleased/gh-10331-tz-in-totable.md b/changelogs/unreleased/gh-10331-tz-in-totable.md new file mode 100644 index 0000000000..d09b3ea7f5 --- /dev/null +++ b/changelogs/unreleased/gh-10331-tz-in-totable.md @@ -0,0 +1,4 @@ +## bugfix/datetime + +* Added the `tz` field to a table produced by `:totable()` + (gh-10331). diff --git a/src/lua/datetime.lua b/src/lua/datetime.lua index c26e1d3aa8..7daecb0761 100644 --- a/src/lua/datetime.lua +++ b/src/lua/datetime.lua @@ -973,6 +973,7 @@ local function datetime_totable(self) isdst = datetime_isdst(self), nsec = self.nsec, tzoffset = self.tzoffset, + tz = self.tz, } end diff --git a/test/app-tap/datetime.test.lua b/test/app-tap/datetime.test.lua index 4cf33d8e06..a7f1c7f5f7 100755 --- a/test/app-tap/datetime.test.lua +++ b/test/app-tap/datetime.test.lua @@ -8,7 +8,7 @@ local json = require('json') local msgpack = require('msgpack') local TZ = date.TZ -test:plan(41) +test:plan(42) local INT_MAX = 2147483647 @@ -151,7 +151,7 @@ test:test("Datetime API checks", function(test) local table_expected = { sec = 0, min = 0, wday = 5, day = 1, nsec = 0, isdst = false, yday = 1, tzoffset = 0, month = 1, - year = 1970, hour = 0 + year = 1970, hour = 0, tz = '' } test:is_deeply(local_totable(ts), table_expected, "correct :totable") local date_expected = date.new() @@ -1832,7 +1832,8 @@ test:test("totable{}", function(test) test:plan(78) local exp = {sec = 0, min = 0, wday = 5, day = 1, nsec = 0, isdst = false, yday = 1, - tzoffset = 0, month = 1, year = 1970, hour = 0} + tzoffset = 0, month = 1, year = 1970, hour = 0, + tz = ''} local ts = date.new() local totable = ts:totable() test:is_deeply(totable, exp, 'date:totable()') @@ -1867,6 +1868,53 @@ test:test("totable{}", function(test) end end) +test:test('totable() with timezone', function(test) + local DEFAULT_TZOFFSET = 0 + local DEFAULT_TZ = '' + + local MOSCOW_TZOFFSET = 180 + local MOSCOW_TZ = 'Europe/Moscow' + + local test_cases = { + -- Empty datetime value except the timezone. + { + dt = {tz = MOSCOW_TZ}, + expected = { + tzoffset = MOSCOW_TZOFFSET, + tz = MOSCOW_TZ, + } + }, + -- Empty datetime value except the tzoffset. + { + dt = {tzoffset = MOSCOW_TZOFFSET}, + expected = { + tzoffset = MOSCOW_TZOFFSET, + tz = '', + } + }, + -- Empty datetime value. + { + dt = {}, + expected = { + tz = DEFAULT_TZ, + tzoffset = DEFAULT_TZOFFSET, + }, + }, + } + + test:plan(#test_cases * 2) + + for _, tc in pairs(test_cases) do + local dtab = date.new(tc.dt):totable() + local expected = tc.expected + test:is(dtab.tzoffset, expected.tzoffset, + ('[tzoffset]: %q == %q'):format(dtab.tzoffset, + expected.tzoffset)) + test:is(dtab.tz, expected.tz, + ('[tz]: %q == %q'):format(dtab.tz, expected.tz)) + end +end) + test:test("Time :set{} operations", function(test) test:plan(16) diff --git a/test/sql-luatest/datetime_test.lua b/test/sql-luatest/datetime_test.lua index 041a809ec3..bd22186a34 100644 --- a/test/sql-luatest/datetime_test.lua +++ b/test/sql-luatest/datetime_test.lua @@ -864,7 +864,8 @@ end g.test_datetime_18_3 = function() g.server:exec(function() local dt = require('datetime') - local dt1 = dt.new({year = 2001, month = 1, day = 1, hour = 1}) + local dt1 = dt.new( + {year = 2001, month = 1, day = 1, hour = 1, tz = 'Z'}) local sql = [[SELECT CAST('2001-01-01T01:00:00Z' AS DATETIME);]] local res = {{dt1}} local rows = box.execute(sql).rows @@ -2218,7 +2219,8 @@ end g.test_datetime_32_1 = function() g.server:exec(function() local dt = require('datetime') - local dt1 = dt.new({year = 2000, month = 2, day = 29, hour = 1}) + local dt1 = dt.new( + {year = 2000, month = 2, day = 29, hour = 1, tz = 'Z'}) local sql = [[SELECT CAST('2000-02-29T01:00:00Z' AS DATETIME);]] local res = {{dt1}} local rows = box.execute(sql).rows -- GitLab