diff --git a/CHANGELOG.md b/CHANGELOG.md index f2636e12a..3b59b9da9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. - Decimal package use a test function GetNumberLength instead of a package-level function getNumberLength (#219) - Datetime location after encode + decode is unequal (#217) +- Wrong interval arithmetic with timezones (#221) ## [1.8.0] - 2022-08-17 diff --git a/datetime/datetime.go b/datetime/datetime.go index 0fe20f572..105d2cca5 100644 --- a/datetime/datetime.go +++ b/datetime/datetime.go @@ -220,6 +220,9 @@ func (dtime *Datetime) Sub(ival Interval) (*Datetime, error) { func (dtime *Datetime) Interval(next *Datetime) Interval { curIval := intervalFromDatetime(dtime) nextIval := intervalFromDatetime(next) + _, curOffset := dtime.time.Zone() + _, nextOffset := next.time.Zone() + curIval.Min -= int64(curOffset-nextOffset) / 60 return nextIval.Sub(curIval) } diff --git a/datetime/datetime_test.go b/datetime/datetime_test.go index 60afa4077..5c63d0f4c 100644 --- a/datetime/datetime_test.go +++ b/datetime/datetime_test.go @@ -321,8 +321,8 @@ func TestDatetimeAddOutOfRange(t *testing.T) { } func TestDatetimeInterval(t *testing.T) { - var first = "2015-03-20T17:50:56.000000009Z" - var second = "2013-01-31T17:51:56.000000009Z" + var first = "2015-03-20T17:50:56.000000009+02:00" + var second = "2013-01-31T11:51:58.00000009+01:00" tmFirst, err := time.Parse(time.RFC3339, first) if err != nil { @@ -345,14 +345,23 @@ func TestDatetimeInterval(t *testing.T) { ivalFirst := dtFirst.Interval(dtSecond) ivalSecond := dtSecond.Interval(dtFirst) - expectedFirst := Interval{-2, -2, 0, 11, 0, 1, 0, 0, NoneAdjust} - expectedSecond := Interval{2, 2, 0, -11, 0, -1, 0, 0, NoneAdjust} + expectedFirst := Interval{-2, -2, 0, 11, -6, 61, 2, 81, NoneAdjust} + expectedSecond := Interval{2, 2, 0, -11, 6, -61, -2, -81, NoneAdjust} if !reflect.DeepEqual(ivalFirst, expectedFirst) { t.Errorf("Unexpected interval %v, expected %v", ivalFirst, expectedFirst) } if !reflect.DeepEqual(ivalSecond, expectedSecond) { - t.Errorf("Unexpected interval %v, expected %v", ivalFirst, expectedSecond) + t.Errorf("Unexpected interval %v, expected %v", ivalSecond, expectedSecond) + } + + dtFirst, err = dtFirst.Add(ivalFirst) + if err != nil { + t.Fatalf("Unable to add an interval: %s", err) + } + if !dtFirst.ToTime().Equal(dtSecond.ToTime()) { + t.Errorf("Incorrect add an interval result: %s, expected %s", + dtFirst.ToTime(), dtSecond.ToTime()) } } @@ -363,12 +372,20 @@ func TestDatetimeTarantoolInterval(t *testing.T) { defer conn.Close() dates := []string{ - "2015-03-20T17:50:56.000000009+01:00", + // We could return tests with timezones after a release with a fix of + // the bug: + // https://github.com/tarantool/tarantool/issues/7698 + // + // "2010-02-24T23:03:56.0000013-04:00", + // "2015-03-20T17:50:56.000000009+01:00", + // "2020-01-01T01:01:01+11:30", + // "2025-08-01T00:00:00.000000003+11:00", + "2010-02-24T23:03:56.0000013Z", + "2015-03-20T17:50:56.000000009Z", + "2020-01-01T01:01:01Z", + "2025-08-01T00:00:00.000000003Z", "2015-12-21T17:50:53Z", - "2010-02-24T23:03:56.0000013-04:00", "1980-03-28T13:18:39.000099Z", - "2025-08-01T00:00:00.000000003+11:00", - "2020-01-01T01:01:01+11:30", } datetimes := []*Datetime{} for _, date := range dates {