commit 37c0664f45c7b74df65384e67c855b22180b482b from: Sergey Bronnikov date: Tue Aug 13 11:50:38 2024 UTC 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) commit - 1b0cc057f3b06138e61a47be4309200186691200 commit + 37c0664f45c7b74df65384e67c855b22180b482b blob - /dev/null blob + d09b3ea7f5ea4919959a0683620cd92e433d8e10 (mode 644) --- /dev/null +++ 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). blob - c26e1d3aa8c696f4e396c7f095c5c28f2faca84e blob + 7daecb0761292325abda5a684bdfc40714869d92 --- src/lua/datetime.lua +++ 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 blob - 4cf33d8e066bd119f09fdc310c01ca568bb78cc9 blob + a7f1c7f5f729a18225f1370e7aad6e35b39e0d6e --- test/app-tap/datetime.test.lua +++ 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()') @@ -1864,6 +1865,53 @@ test:test("totable{}", function(test) for _, key in pairs({'wday', 'day', 'yday', 'month', 'year'}) do test:is(ts[key], osdate[key], ('[%s]: %s == %s'):format(key, ts[key], osdate[key])) + 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) blob - 041a809ec3cece2a8ea9b6091160c0e308530891 blob + bd22186a3430cd85f3de21b70fb3aaef21e9916e --- test/sql-luatest/datetime_test.lua +++ 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