From 8aa134746c7acb80bf02710974246b443735db20 Mon Sep 17 00:00:00 2001 From: Timur Safin <tsafin@tarantool.org> Date: Mon, 3 Oct 2022 17:10:45 +0300 Subject: [PATCH] datetime: datetimes subtractions ignored timezone We used to ignore timezone difference (in `tzoffset`) for datetime subtraction operation: ``` tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'} --- - +0 seconds ... tarantool> datetime.new{tz='MSK'}.timestamp - datetime.new{tz='UTC'}.timestamp --- - -10800 ... ``` Now we accumulate tzoffset difference in the minute component of a resultant interval: ``` tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'} --- - -180 minutes ... ``` Closes #7698 NO_DOC=bugfix (cherry picked from commit 0daed8d5539b291cce3d82eb63756684af792c22) --- .../gh-7698-datetime-subtraction-with-tz.md | 28 +++++++++++++++++++ src/lib/core/datetime.c | 1 + test/app-tap/datetime.test.lua | 16 ++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/gh-7698-datetime-subtraction-with-tz.md diff --git a/changelogs/unreleased/gh-7698-datetime-subtraction-with-tz.md b/changelogs/unreleased/gh-7698-datetime-subtraction-with-tz.md new file mode 100644 index 0000000000..3e11cd52c0 --- /dev/null +++ b/changelogs/unreleased/gh-7698-datetime-subtraction-with-tz.md @@ -0,0 +1,28 @@ +## bugfix/datetime + +* Fixed subtractions for datetimes with different timezones (gh-7698). + + We used to ignore timezone difference (im `tzoffset`) for + datetime subtraction operation: + + ``` + tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'} + --- + - +0 seconds + ... + tarantool> datetime.new{tz='MSK'}.timestamp - + datetime.new{tz='UTC'}.timestamp + --- + - -10800 + ... + ``` + + Now we accumulate that difference to the minute component of + a resultant interval: + + ``` + tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'} + --- + - -180 minutes + ... + ``` diff --git a/src/lib/core/datetime.c b/src/lib/core/datetime.c index e1e85457a9..e22504d2fb 100644 --- a/src/lib/core/datetime.c +++ b/src/lib/core/datetime.c @@ -844,6 +844,7 @@ datetime_datetime_sub(struct interval *res, const struct datetime *lhs, struct interval inv_rhs; datetime_totable(lhs, res); datetime_totable(rhs, &inv_rhs); + res->min -= lhs->tzoffset - rhs->tzoffset; return interval_interval_sub(res, &inv_rhs); } diff --git a/test/app-tap/datetime.test.lua b/test/app-tap/datetime.test.lua index b08b0dd26a..cb06b0a65b 100755 --- a/test/app-tap/datetime.test.lua +++ b/test/app-tap/datetime.test.lua @@ -12,7 +12,7 @@ local TZ = date.TZ --]] if jit.arch == 'arm64' then jit.off() end -test:plan(38) +test:plan(39) -- minimum supported date - -5879610-06-22 local MIN_DATE_YEAR = -5879610 @@ -1257,6 +1257,20 @@ test:test("Time interval operations - different adjustments", function(test) end end) +test:test("Time interval operations - different timezones", function(test) + test:plan(8) + local d1_msk = date.new{tz = 'MSK'} + local d1_utc = date.new{tz = 'UTC'} + test:is(d1_msk.tzoffset, 180, 'MSK is +180') + test:is(d1_utc.tzoffset, 0, 'UTC is 0') + test:is(tostring(d1_msk), '1970-01-01T00:00:00 MSK', '1970-01-01 MSK') + test:is(tostring(d1_utc), '1970-01-01T00:00:00 UTC', '1970-01-01 UTC') + test:is(d1_utc > d1_msk, true, 'utc > msk') + test:is(tostring(d1_utc - d1_msk), '+180 minutes', 'utc - msk') + test:is(tostring(d1_msk - d1_utc), '-180 minutes', 'msk - utc') + test:is(d1_msk.epoch - d1_utc.epoch, -10800, '-10800') +end) + test:test("Time intervals creation - range checks", function(test) test:plan(23) -- GitLab