github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/time/zoneinfo_test.go (about) 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. 4 5 package time_test 6 7 import ( 8 "errors" 9 "fmt" 10 "internal/testenv" 11 "os" 12 "reflect" 13 "testing" 14 "time" 15 ) 16 17 func init() { 18 if time.ZoneinfoForTesting() != nil { 19 panic(fmt.Errorf("zoneinfo initialized before first LoadLocation")) 20 } 21 } 22 23 func TestEnvVarUsage(t *testing.T) { 24 time.ResetZoneinfoForTesting() 25 26 const testZoneinfo = "foo.zip" 27 const env = "ZONEINFO" 28 29 t.Setenv(env, testZoneinfo) 30 31 // Result isn't important, we're testing the side effect of this command 32 time.LoadLocation("Asia/Jerusalem") 33 defer time.ResetZoneinfoForTesting() 34 35 if zoneinfo := time.ZoneinfoForTesting(); testZoneinfo != *zoneinfo { 36 t.Errorf("zoneinfo does not match env variable: got %q want %q", *zoneinfo, testZoneinfo) 37 } 38 } 39 40 func TestBadLocationErrMsg(t *testing.T) { 41 time.ResetZoneinfoForTesting() 42 loc := "Asia/SomethingNotExist" 43 want := errors.New("unknown time zone " + loc) 44 _, err := time.LoadLocation(loc) 45 if err.Error() != want.Error() { 46 t.Errorf("LoadLocation(%q) error = %v; want %v", loc, err, want) 47 } 48 } 49 50 func TestLoadLocationValidatesNames(t *testing.T) { 51 time.ResetZoneinfoForTesting() 52 const env = "ZONEINFO" 53 t.Setenv(env, "") 54 55 bad := []string{ 56 "/usr/foo/Foo", 57 "\\UNC\foo", 58 "..", 59 "a..", 60 } 61 for _, v := range bad { 62 _, err := time.LoadLocation(v) 63 if err != time.ErrLocation { 64 t.Errorf("LoadLocation(%q) error = %v; want ErrLocation", v, err) 65 } 66 } 67 } 68 69 func TestVersion3(t *testing.T) { 70 undo := time.DisablePlatformSources() 71 defer undo() 72 _, err := time.LoadLocation("Asia/Jerusalem") 73 if err != nil { 74 t.Fatal(err) 75 } 76 } 77 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 undo := time.DisablePlatformSources() 83 defer undo() 84 85 const format = "Mon, 02 Jan 2006 15:04:05 -0700 (MST)" 86 var tests = []struct { 87 zone string 88 unix int64 89 want1 string 90 want2 string 91 }{ 92 { 93 "PST8PDT", 94 -1633269601, 95 "Sun, 31 Mar 1918 01:59:59 -0800 (PST)", 96 "Sun, 31 Mar 1918 03:00:00 -0700 (PDT)", 97 }, 98 { 99 "Pacific/Fakaofo", 100 1325242799, 101 "Thu, 29 Dec 2011 23:59:59 -1100 (-11)", 102 "Sat, 31 Dec 2011 00:00:00 +1300 (+13)", 103 }, 104 } 105 106 for _, test := range tests { 107 z, err := time.LoadLocation(test.zone) 108 if err != nil { 109 t.Fatal(err) 110 } 111 s := time.Unix(test.unix, 0).In(z).Format(format) 112 if s != test.want1 { 113 t.Errorf("for %s %d got %q want %q", test.zone, test.unix, s, test.want1) 114 } 115 s = time.Unix(test.unix+1, 0).In(z).Format(format) 116 if s != test.want2 { 117 t.Errorf("for %s %d got %q want %q", test.zone, test.unix, s, test.want2) 118 } 119 } 120 } 121 122 func TestLocationNames(t *testing.T) { 123 if time.Local.String() != "Local" { 124 t.Errorf(`invalid Local location name: got %q want "Local"`, time.Local) 125 } 126 if time.UTC.String() != "UTC" { 127 t.Errorf(`invalid UTC location name: got %q want "UTC"`, time.UTC) 128 } 129 } 130 131 func TestLoadLocationFromTZData(t *testing.T) { 132 undo := time.DisablePlatformSources() 133 defer undo() 134 135 const locationName = "Asia/Jerusalem" 136 reference, err := time.LoadLocation(locationName) 137 if err != nil { 138 t.Fatal(err) 139 } 140 141 gorootSource, ok := time.GorootZoneSource(testenv.GOROOT(t)) 142 if !ok { 143 t.Fatal("Failed to locate tzinfo source in GOROOT.") 144 } 145 tzinfo, err := time.LoadTzinfo(locationName, gorootSource) 146 if err != nil { 147 t.Fatal(err) 148 } 149 sample, err := time.LoadLocationFromTZData(locationName, tzinfo) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 if !reflect.DeepEqual(reference, sample) { 155 t.Errorf("return values of LoadLocationFromTZData and LoadLocation don't match") 156 } 157 } 158 159 // Issue 30099. 160 func TestEarlyLocation(t *testing.T) { 161 undo := time.DisablePlatformSources() 162 defer undo() 163 164 const locName = "America/New_York" 165 loc, err := time.LoadLocation(locName) 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 d := time.Date(1900, time.January, 1, 0, 0, 0, 0, loc) 171 tzName, tzOffset := d.Zone() 172 if want := "EST"; tzName != want { 173 t.Errorf("Zone name == %s, want %s", tzName, want) 174 } 175 if want := -18000; tzOffset != want { 176 t.Errorf("Zone offset == %d, want %d", tzOffset, want) 177 } 178 } 179 180 func TestMalformedTZData(t *testing.T) { 181 // The goal here is just that malformed tzdata results in an error, not a panic. 182 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" 183 _, err := time.LoadLocationFromTZData("abc", []byte(issue29437)) 184 if err == nil { 185 t.Error("expected error, got none") 186 } 187 } 188 189 var slimTests = []struct { 190 zoneName string 191 fileName string 192 date func(*time.Location) time.Time 193 wantName string 194 wantOffset int 195 }{ 196 { 197 // 2020b slim tzdata for Europe/Berlin. 198 zoneName: "Europe/Berlin", 199 fileName: "2020b_Europe_Berlin", 200 date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) }, 201 wantName: "CET", 202 wantOffset: 3600, 203 }, 204 { 205 // 2021a slim tzdata for America/Nuuk. 206 zoneName: "America/Nuuk", 207 fileName: "2021a_America_Nuuk", 208 date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) }, 209 wantName: "-03", 210 wantOffset: -10800, 211 }, 212 { 213 // 2021a slim tzdata for Asia/Gaza. 214 zoneName: "Asia/Gaza", 215 fileName: "2021a_Asia_Gaza", 216 date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) }, 217 wantName: "EET", 218 wantOffset: 7200, 219 }, 220 { 221 // 2021a slim tzdata for Europe/Dublin. 222 zoneName: "Europe/Dublin", 223 fileName: "2021a_Europe_Dublin", 224 date: func(loc *time.Location) time.Time { return time.Date(2021, time.April, 2, 11, 12, 13, 0, loc) }, 225 wantName: "IST", 226 wantOffset: 3600, 227 }, 228 } 229 230 func TestLoadLocationFromTZDataSlim(t *testing.T) { 231 for _, test := range slimTests { 232 tzData, err := os.ReadFile("testdata/" + test.fileName) 233 if err != nil { 234 t.Error(err) 235 continue 236 } 237 reference, err := time.LoadLocationFromTZData(test.zoneName, tzData) 238 if err != nil { 239 t.Error(err) 240 continue 241 } 242 243 d := test.date(reference) 244 tzName, tzOffset := d.Zone() 245 if tzName != test.wantName { 246 t.Errorf("Zone name == %s, want %s", tzName, test.wantName) 247 } 248 if tzOffset != test.wantOffset { 249 t.Errorf("Zone offset == %d, want %d", tzOffset, test.wantOffset) 250 } 251 } 252 } 253 254 func TestTzset(t *testing.T) { 255 for _, test := range []struct { 256 inStr string 257 inEnd int64 258 inSec int64 259 name string 260 off int 261 start int64 262 end int64 263 isDST bool 264 ok bool 265 }{ 266 {"", 0, 0, "", 0, 0, 0, false, false}, 267 {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true}, 268 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, false, true}, 269 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true}, 270 {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true}, 271 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true}, 272 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true}, 273 {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true}, 274 {"KST-9", 592333200, 1677246697, "KST", 9 * 60 * 60, 592333200, 1<<63 - 1, false, true}, 275 } { 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) 279 } 280 } 281 } 282 283 func TestTzsetName(t *testing.T) { 284 for _, test := range []struct { 285 in string 286 name string 287 out string 288 ok bool 289 }{ 290 {"", "", "", false}, 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}, 296 } { 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) 300 } 301 } 302 } 303 304 func TestTzsetOffset(t *testing.T) { 305 for _, test := range []struct { 306 in string 307 off int 308 out string 309 ok bool 310 }{ 311 {"", 0, "", false}, 312 {"X", 0, "", false}, 313 {"+", 0, "", false}, 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}, 320 } { 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) 324 } 325 } 326 } 327 328 func TestTzsetRule(t *testing.T) { 329 for _, test := range []struct { 330 in string 331 r time.Rule 332 out string 333 ok bool 334 }{ 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}, 344 } { 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) 348 } 349 } 350 }