1
0
mirror of https://github.com/golang/go synced 2024-11-05 12:16:10 -07:00

time: fix AddDate with nil location

AddDate now retrieves location from t.Location() to ensure that
it never calls Date with a nil location.

Added test for this bug on all Time's methods

Fixes #15852

Change-Id: Id2a222af56993f741ad0b802a2c3b89e8e463926
Reviewed-on: https://go-review.googlesource.com/23561
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
Simon Rawet 2016-05-28 16:46:45 +02:00 committed by Brad Fitzpatrick
parent c79ba22ece
commit b4f3c9339e
2 changed files with 93 additions and 1 deletions

View File

@ -657,7 +657,7 @@ func Until(t Time) Duration {
func (t Time) AddDate(years int, months int, days int) Time {
year, month, day := t.Date()
hour, min, sec := t.Clock()
return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec), t.loc)
return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec), t.Location())
}
const (

View File

@ -1039,6 +1039,98 @@ func TestDurationHours(t *testing.T) {
}
}
var defaultLocTests = []struct {
name string
f func(t1, t2 Time) bool
}{
{"After", func(t1, t2 Time) bool { return t1.After(t2) == t2.After(t1) }},
{"Before", func(t1, t2 Time) bool { return t1.Before(t2) == t2.Before(t1) }},
{"Equal", func(t1, t2 Time) bool { return t1.Equal(t2) == t2.Equal(t1) }},
{"IsZero", func(t1, t2 Time) bool { return t1.IsZero() == t2.IsZero() }},
{"Date", func(t1, t2 Time) bool {
a1, b1, c1 := t1.Date()
a2, b2, c2 := t2.Date()
return a1 == a2 && b1 == b2 && c1 == c2
}},
{"Year", func(t1, t2 Time) bool { return t1.Year() == t2.Year() }},
{"Month", func(t1, t2 Time) bool { return t1.Month() == t2.Month() }},
{"Day", func(t1, t2 Time) bool { return t1.Day() == t2.Day() }},
{"Weekday", func(t1, t2 Time) bool { return t1.Weekday() == t2.Weekday() }},
{"ISOWeek", func(t1, t2 Time) bool {
a1, b1 := t1.ISOWeek()
a2, b2 := t2.ISOWeek()
return a1 == a2 && b1 == b2
}},
{"Clock", func(t1, t2 Time) bool {
a1, b1, c1 := t1.Clock()
a2, b2, c2 := t2.Clock()
return a1 == a2 && b1 == b2 && c1 == c2
}},
{"Hour", func(t1, t2 Time) bool { return t1.Hour() == t2.Hour() }},
{"Minute", func(t1, t2 Time) bool { return t1.Minute() == t2.Minute() }},
{"Second", func(t1, t2 Time) bool { return t1.Second() == t2.Second() }},
{"Nanosecond", func(t1, t2 Time) bool { return t1.Hour() == t2.Hour() }},
{"YearDay", func(t1, t2 Time) bool { return t1.YearDay() == t2.YearDay() }},
// Using Equal since Add don't modify loc using "==" will cause a fail
{"Add", func(t1, t2 Time) bool { return t1.Add(Hour).Equal(t2.Add(Hour)) }},
{"Sub", func(t1, t2 Time) bool { return t1.Sub(t2) == t2.Sub(t1) }},
//Original caus for this test case bug 15852
{"AddDate", func(t1, t2 Time) bool { return t1.AddDate(1991, 9, 3) == t2.AddDate(1991, 9, 3) }},
{"UTC", func(t1, t2 Time) bool { return t1.UTC() == t2.UTC() }},
{"Local", func(t1, t2 Time) bool { return t1.Local() == t2.Local() }},
{"In", func(t1, t2 Time) bool { return t1.In(UTC) == t2.In(UTC) }},
{"Local", func(t1, t2 Time) bool { return t1.Local() == t2.Local() }},
{"Zone", func(t1, t2 Time) bool {
a1, b1 := t1.Zone()
a2, b2 := t2.Zone()
return a1 == a2 && b1 == b2
}},
{"Unix", func(t1, t2 Time) bool { return t1.Unix() == t2.Unix() }},
{"UnixNano", func(t1, t2 Time) bool { return t1.UnixNano() == t2.UnixNano() }},
{"MarshalBinary", func(t1, t2 Time) bool {
a1, b1 := t1.MarshalBinary()
a2, b2 := t2.MarshalBinary()
return bytes.Equal(a1, a2) && b1 == b2
}},
{"GobEncode", func(t1, t2 Time) bool {
a1, b1 := t1.GobEncode()
a2, b2 := t2.GobEncode()
return bytes.Equal(a1, a2) && b1 == b2
}},
{"MarshalJSON", func(t1, t2 Time) bool {
a1, b1 := t1.MarshalJSON()
a2, b2 := t2.MarshalJSON()
return bytes.Equal(a1, a2) && b1 == b2
}},
{"MarshalText", func(t1, t2 Time) bool {
a1, b1 := t1.MarshalText()
a2, b2 := t2.MarshalText()
return bytes.Equal(a1, a2) && b1 == b2
}},
{"Truncate", func(t1, t2 Time) bool { return t1.Truncate(Hour).Equal(t2.Truncate(Hour)) }},
{"Round", func(t1, t2 Time) bool { return t1.Round(Hour).Equal(t2.Round(Hour)) }},
}
func TestDefaultLoc(t *testing.T) {
//This test verifyes that all Time's methods behaves identical if loc is set
//as nil or UTC
for _, tt := range defaultLocTests {
t1 := Time{}
t2 := Time{}.UTC()
if !tt.f(t1, t2) {
t.Errorf("Default fail on fuction: %s", tt.name)
}
}
}
func BenchmarkNow(b *testing.B) {
for i := 0; i < b.N; i++ {
t = Now()