1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 if time
.ZoneinfoForTesting() != nil {
18 panic(fmt
.Errorf("zoneinfo initialized before first LoadLocation"))
22 func TestEnvVarUsage(t
*testing
.T
) {
23 time
.ResetZoneinfoForTesting()
25 const testZoneinfo
= "foo.zip"
26 const env
= "ZONEINFO"
28 t
.Setenv(env
, testZoneinfo
)
30 // Result isn't important, we're testing the side effect of this command
31 time
.LoadLocation("Asia/Jerusalem")
32 defer time
.ResetZoneinfoForTesting()
34 if zoneinfo
:= time
.ZoneinfoForTesting(); testZoneinfo
!= *zoneinfo
{
35 t
.Errorf("zoneinfo does not match env variable: got %q want %q", *zoneinfo
, testZoneinfo
)
39 func TestBadLocationErrMsg(t
*testing
.T
) {
40 time
.ResetZoneinfoForTesting()
41 loc
:= "Asia/SomethingNotExist"
42 want
:= errors
.New("unknown time zone " + loc
)
43 _
, err
:= time
.LoadLocation(loc
)
44 if err
.Error() != want
.Error() {
45 t
.Errorf("LoadLocation(%q) error = %v; want %v", loc
, err
, want
)
49 func TestLoadLocationValidatesNames(t
*testing
.T
) {
50 time
.ResetZoneinfoForTesting()
51 const env
= "ZONEINFO"
60 for _
, v
:= range bad
{
61 _
, err
:= time
.LoadLocation(v
)
62 if err
!= time
.ErrLocation
{
63 t
.Errorf("LoadLocation(%q) error = %v; want ErrLocation", v
, err
)
68 func TestVersion3(t
*testing
.T
) {
69 t
.Skip("gccgo does not use the zip file")
70 time
.ForceZipFileForTesting(true)
71 defer time
.ForceZipFileForTesting(false)
72 _
, err
:= time
.LoadLocation("Asia/Jerusalem")
78 // Test that we get the correct results for times before the first
79 // transition time. To do this we explicitly check early dates in a
80 // couple of specific timezones.
81 func TestFirstZone(t
*testing
.T
) {
82 t
.Skip("gccgo does not use the zip file")
84 time
.ForceZipFileForTesting(true)
85 defer time
.ForceZipFileForTesting(false)
87 const format
= "Mon, 02 Jan 2006 15:04:05 -0700 (MST)"
88 var tests
= []struct {
97 "Sun, 31 Mar 1918 01:59:59 -0800 (PST)",
98 "Sun, 31 Mar 1918 03:00:00 -0700 (PDT)",
103 "Thu, 29 Dec 2011 23:59:59 -1100 (-11)",
104 "Sat, 31 Dec 2011 00:00:00 +1300 (+13)",
108 for _
, test
:= range tests
{
109 z
, err
:= time
.LoadLocation(test
.zone
)
113 s
:= time
.Unix(test
.unix
, 0).In(z
).Format(format
)
115 t
.Errorf("for %s %d got %q want %q", test
.zone
, test
.unix
, s
, test
.want1
)
117 s
= time
.Unix(test
.unix
+1, 0).In(z
).Format(format
)
119 t
.Errorf("for %s %d got %q want %q", test
.zone
, test
.unix
, s
, test
.want2
)
124 func TestLocationNames(t
*testing
.T
) {
125 if time
.Local
.String() != "Local" {
126 t
.Errorf(`invalid Local location name: got %q want "Local"`, time
.Local
)
128 if time
.UTC
.String() != "UTC" {
129 t
.Errorf(`invalid UTC location name: got %q want "UTC"`, time
.UTC
)
133 func TestLoadLocationFromTZData(t
*testing
.T
) {
134 t
.Skip("gccgo does not use the zip file")
136 time
.ForceZipFileForTesting(true)
137 defer time
.ForceZipFileForTesting(false)
139 const locationName
= "Asia/Jerusalem"
140 reference
, err
:= time
.LoadLocation(locationName
)
145 tzinfo
, err
:= time
.LoadTzinfo(locationName
, time
.OrigZoneSources
[len(time
.OrigZoneSources
)-1])
149 sample
, err
:= time
.LoadLocationFromTZData(locationName
, tzinfo
)
154 if !reflect
.DeepEqual(reference
, sample
) {
155 t
.Errorf("return values of LoadLocationFromTZData and LoadLocation don't match")
160 func TestEarlyLocation(t
*testing
.T
) {
161 t
.Skip("gccgo does not use the zip file")
162 time
.ForceZipFileForTesting(true)
163 defer time
.ForceZipFileForTesting(false)
165 const locName
= "America/New_York"
166 loc
, err
:= time
.LoadLocation(locName
)
171 d
:= time
.Date(1900, time
.January
, 1, 0, 0, 0, 0, loc
)
172 tzName
, tzOffset
:= d
.Zone()
173 if want
:= "EST"; tzName
!= want
{
174 t
.Errorf("Zone name == %s, want %s", tzName
, want
)
176 if want
:= -18000; tzOffset
!= want
{
177 t
.Errorf("Zone offset == %d, want %d", tzOffset
, want
)
181 func TestMalformedTZData(t
*testing
.T
) {
182 // The goal here is just that malformed tzdata results in an error, not a panic.
183 issue29437
:= "TZif\x00000000000000000\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0000"
184 _
, err
:= time
.LoadLocationFromTZData("abc", []byte(issue29437
))
186 t
.Error("expected error, got none")
190 var slimTests
= []struct {
193 date
func(*time
.Location
) time
.Time
198 // 2020b slim tzdata for Europe/Berlin.
199 zoneName
: "Europe/Berlin",
200 fileName
: "2020b_Europe_Berlin",
201 date
: func(loc
*time
.Location
) time
.Time
{ return time
.Date(2020, time
.October
, 29, 15, 30, 0, 0, loc
) },
206 // 2021a slim tzdata for America/Nuuk.
207 zoneName
: "America/Nuuk",
208 fileName
: "2021a_America_Nuuk",
209 date
: func(loc
*time
.Location
) time
.Time
{ return time
.Date(2020, time
.October
, 29, 15, 30, 0, 0, loc
) },
214 // 2021a slim tzdata for Asia/Gaza.
215 zoneName
: "Asia/Gaza",
216 fileName
: "2021a_Asia_Gaza",
217 date
: func(loc
*time
.Location
) time
.Time
{ return time
.Date(2020, time
.October
, 29, 15, 30, 0, 0, loc
) },
222 // 2021a slim tzdata for Europe/Dublin.
223 zoneName
: "Europe/Dublin",
224 fileName
: "2021a_Europe_Dublin",
225 date
: func(loc
*time
.Location
) time
.Time
{ return time
.Date(2021, time
.April
, 2, 11, 12, 13, 0, loc
) },
231 func TestLoadLocationFromTZDataSlim(t
*testing
.T
) {
232 for _
, test
:= range slimTests
{
233 tzData
, err
:= os
.ReadFile("testdata/" + test
.fileName
)
238 reference
, err
:= time
.LoadLocationFromTZData(test
.zoneName
, tzData
)
244 d
:= test
.date(reference
)
245 tzName
, tzOffset
:= d
.Zone()
246 if tzName
!= test
.wantName
{
247 t
.Errorf("Zone name == %s, want %s", tzName
, test
.wantName
)
249 if tzOffset
!= test
.wantOffset
{
250 t
.Errorf("Zone offset == %d, want %d", tzOffset
, test
.wantOffset
)
255 func TestTzset(t
*testing
.T
) {
256 for _
, test
:= range []struct {
267 {"", 0, 0, "", 0, 0, 0, false, false},
268 {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
269 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, false, true},
270 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
271 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
272 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
273 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
274 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
276 name
, off
, start
, end
, isDST
, ok
:= time
.Tzset(test
.inStr
, test
.inEnd
, test
.inSec
)
277 if name
!= test
.name || off
!= test
.off || start
!= test
.start || end
!= test
.end || isDST
!= test
.isDST || ok
!= test
.ok
{
278 t
.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, %t, want %q, %d, %d, %d, %t, %t", test
.inStr
, test
.inEnd
, test
.inSec
, name
, off
, start
, end
, isDST
, ok
, test
.name
, test
.off
, test
.start
, test
.end
, test
.isDST
, test
.ok
)
283 func TestTzsetName(t
*testing
.T
) {
284 for _
, test
:= range []struct {
291 {"X", "", "", false},
292 {"PST", "PST", "", true},
293 {"PST8PDT", "PST", "8PDT", true},
294 {"PST-08", "PST", "-08", true},
295 {"<A+B>+08", "A+B", "+08", true},
297 name
, out
, ok
:= time
.TzsetName(test
.in
)
298 if name
!= test
.name || out
!= test
.out || ok
!= test
.ok
{
299 t
.Errorf("tzsetName(%q) = %q, %q, %t, want %q, %q, %t", test
.in
, name
, out
, ok
, test
.name
, test
.out
, test
.ok
)
304 func TestTzsetOffset(t
*testing
.T
) {
305 for _
, test
:= range []struct {
314 {"+08", 8 * 60 * 60, "", true},
315 {"-01:02:03", -1*60*60 - 2*60 - 3, "", true},
316 {"01", 1 * 60 * 60, "", true},
317 {"100", 100 * 60 * 60, "", true},
318 {"1000", 0, "", false},
319 {"8PDT", 8 * 60 * 60, "PDT", true},
321 off
, out
, ok
:= time
.TzsetOffset(test
.in
)
322 if off
!= test
.off || out
!= test
.out || ok
!= test
.ok
{
323 t
.Errorf("tzsetName(%q) = %d, %q, %t, want %d, %q, %t", test
.in
, off
, out
, ok
, test
.off
, test
.out
, test
.ok
)
328 func TestTzsetRule(t
*testing
.T
) {
329 for _
, test
:= range []struct {
335 {"", time
.Rule
{}, "", false},
336 {"X", time
.Rule
{}, "", false},
337 {"J10", time
.Rule
{Kind
: time
.RuleJulian
, Day
: 10, Time
: 2 * 60 * 60}, "", true},
338 {"20", time
.Rule
{Kind
: time
.RuleDOY
, Day
: 20, Time
: 2 * 60 * 60}, "", true},
339 {"M1.2.3", time
.Rule
{Kind
: time
.RuleMonthWeekDay
, Mon
: 1, Week
: 2, Day
: 3, Time
: 2 * 60 * 60}, "", true},
340 {"30/03:00:00", time
.Rule
{Kind
: time
.RuleDOY
, Day
: 30, Time
: 3 * 60 * 60}, "", true},
341 {"M4.5.6/03:00:00", time
.Rule
{Kind
: time
.RuleMonthWeekDay
, Mon
: 4, Week
: 5, Day
: 6, Time
: 3 * 60 * 60}, "", true},
342 {"M4.5.7/03:00:00", time
.Rule
{}, "", false},
343 {"M4.5.6/-04", time
.Rule
{Kind
: time
.RuleMonthWeekDay
, Mon
: 4, Week
: 5, Day
: 6, Time
: -4 * 60 * 60}, "", true},
345 r
, out
, ok
:= time
.TzsetRule(test
.in
)
346 if r
!= test
.r || out
!= test
.out || ok
!= test
.ok
{
347 t
.Errorf("tzsetName(%q) = %#v, %q, %t, want %#v, %q, %t", test
.in
, r
, out
, ok
, test
.r
, test
.out
, test
.ok
)