tzinfo 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tzinfo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGES.md +122 -1
- data/LICENSE +1 -1
- data/Rakefile +4 -1
- data/lib/tzinfo/timezone.rb +55 -23
- data/lib/tzinfo/timezone_offset.rb +4 -0
- data/lib/tzinfo/timezone_period.rb +18 -1
- data/lib/tzinfo/timezone_proxy.rb +29 -0
- data/lib/tzinfo/zoneinfo_data_source.rb +4 -4
- data/lib/tzinfo/zoneinfo_timezone_info.rb +107 -58
- data/test/tc_country.rb +4 -4
- data/test/tc_ruby_data_source.rb +4 -4
- data/test/tc_timezone.rb +32 -16
- data/test/tc_timezone_proxy.rb +39 -25
- data/test/tc_zoneinfo_data_source.rb +85 -14
- data/test/tc_zoneinfo_timezone_info.rb +331 -17
- data/test/test_utils.rb +3 -1
- data/tzinfo.gemspec +1 -1
- metadata +10 -10
- metadata.gz.sig +0 -0
data/test/tc_country.rb
CHANGED
@@ -47,7 +47,7 @@ class TCCountry < Minitest::Test
|
|
47
47
|
Country.get('GB')
|
48
48
|
|
49
49
|
safe_test do
|
50
|
-
code = 'GB'.taint
|
50
|
+
code = 'GB'.dup.taint
|
51
51
|
assert(code.tainted?)
|
52
52
|
country = Country.get(code)
|
53
53
|
assert_equal('GB', country.code)
|
@@ -59,14 +59,14 @@ class TCCountry < Minitest::Test
|
|
59
59
|
Country.get('GB')
|
60
60
|
|
61
61
|
safe_test do
|
62
|
-
country = Country.get('GB'.taint.freeze)
|
62
|
+
country = Country.get('GB'.dup.taint.freeze)
|
63
63
|
assert_equal('GB', country.code)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
def test_get_tainted_not_previously_loaded
|
68
68
|
safe_test do
|
69
|
-
code = 'GB'.taint
|
69
|
+
code = 'GB'.dup.taint
|
70
70
|
assert(code.tainted?)
|
71
71
|
country = Country.get(code)
|
72
72
|
assert_equal('GB', country.code)
|
@@ -76,7 +76,7 @@ class TCCountry < Minitest::Test
|
|
76
76
|
|
77
77
|
def test_get_tainted_and_frozen_not_previously_loaded
|
78
78
|
safe_test do
|
79
|
-
country = Country.get('GB'.taint.freeze)
|
79
|
+
country = Country.get('GB'.dup.taint.freeze)
|
80
80
|
assert_equal('GB', country.code)
|
81
81
|
end
|
82
82
|
end
|
data/test/tc_ruby_data_source.rb
CHANGED
@@ -56,7 +56,7 @@ class TCRubyDataSource < Minitest::Test
|
|
56
56
|
|
57
57
|
def test_load_timezone_info_tainted
|
58
58
|
safe_test do
|
59
|
-
identifier = 'Europe/Amsterdam'.taint
|
59
|
+
identifier = 'Europe/Amsterdam'.dup.taint
|
60
60
|
assert(identifier.tainted?)
|
61
61
|
info = @data_source.load_timezone_info(identifier)
|
62
62
|
assert_equal('Europe/Amsterdam', info.identifier)
|
@@ -66,7 +66,7 @@ class TCRubyDataSource < Minitest::Test
|
|
66
66
|
|
67
67
|
def test_load_timezone_info_tainted_and_frozen
|
68
68
|
safe_test do
|
69
|
-
info = @data_source.load_timezone_info('Europe/Amsterdam'.taint.freeze)
|
69
|
+
info = @data_source.load_timezone_info('Europe/Amsterdam'.dup.taint.freeze)
|
70
70
|
assert_equal('Europe/Amsterdam', info.identifier)
|
71
71
|
end
|
72
72
|
end
|
@@ -120,7 +120,7 @@ class TCRubyDataSource < Minitest::Test
|
|
120
120
|
|
121
121
|
def test_load_country_info_tainted
|
122
122
|
safe_test do
|
123
|
-
code = 'NL'.taint
|
123
|
+
code = 'NL'.dup.taint
|
124
124
|
assert(code.tainted?)
|
125
125
|
info = @data_source.load_country_info(code)
|
126
126
|
assert_equal('NL', info.code)
|
@@ -130,7 +130,7 @@ class TCRubyDataSource < Minitest::Test
|
|
130
130
|
|
131
131
|
def test_load_country_info_tainted_and_frozen
|
132
132
|
safe_test do
|
133
|
-
info = @data_source.load_country_info('NL'.taint.freeze)
|
133
|
+
info = @data_source.load_country_info('NL'.dup.taint.freeze)
|
134
134
|
assert_equal('NL', info.code)
|
135
135
|
end
|
136
136
|
end
|
data/test/tc_timezone.rb
CHANGED
@@ -243,7 +243,7 @@ class TCTimezone < Minitest::Test
|
|
243
243
|
Timezone.get('Europe/Andorra')
|
244
244
|
|
245
245
|
safe_test do
|
246
|
-
identifier = 'Europe/Andorra'.taint
|
246
|
+
identifier = 'Europe/Andorra'.dup.taint
|
247
247
|
assert(identifier.tainted?)
|
248
248
|
tz = Timezone.get(identifier)
|
249
249
|
assert_equal('Europe/Andorra', tz.identifier)
|
@@ -255,14 +255,14 @@ class TCTimezone < Minitest::Test
|
|
255
255
|
Timezone.get('Europe/Andorra')
|
256
256
|
|
257
257
|
safe_test do
|
258
|
-
tz = Timezone.get('Europe/Andorra'.taint.freeze)
|
258
|
+
tz = Timezone.get('Europe/Andorra'.dup.taint.freeze)
|
259
259
|
assert_equal('Europe/Andorra', tz.identifier)
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
263
|
def test_get_tainted_not_previously_loaded
|
264
264
|
safe_test do
|
265
|
-
identifier = 'Europe/Andorra'.taint
|
265
|
+
identifier = 'Europe/Andorra'.dup.taint
|
266
266
|
assert(identifier.tainted?)
|
267
267
|
tz = Timezone.get(identifier)
|
268
268
|
assert_equal('Europe/Andorra', tz.identifier)
|
@@ -272,7 +272,7 @@ class TCTimezone < Minitest::Test
|
|
272
272
|
|
273
273
|
def test_get_tainted_and_frozen_not_previously_loaded
|
274
274
|
safe_test do
|
275
|
-
tz = Timezone.get('Europe/Amsterdam'.taint.freeze)
|
275
|
+
tz = Timezone.get('Europe/Amsterdam'.dup.taint.freeze)
|
276
276
|
assert_equal('Europe/Amsterdam', tz.identifier)
|
277
277
|
end
|
278
278
|
end
|
@@ -436,6 +436,13 @@ class TCTimezone < Minitest::Test
|
|
436
436
|
assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier)
|
437
437
|
end
|
438
438
|
|
439
|
+
if defined?(Encoding)
|
440
|
+
def test_friendly_identifier_non_binary_encoding
|
441
|
+
refute_equal(Encoding::ASCII_8BIT, TestTimezone.new('Europe/Paris').friendly_identifier(true).encoding)
|
442
|
+
refute_equal(Encoding::ASCII_8BIT, TestTimezone.new('Europe/Paris').friendly_identifier(false).encoding)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
439
446
|
def test_to_s
|
440
447
|
assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').to_s)
|
441
448
|
assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').to_s)
|
@@ -1246,26 +1253,35 @@ class TCTimezone < Minitest::Test
|
|
1246
1253
|
|
1247
1254
|
def test_strftime_datetime
|
1248
1255
|
tz = Timezone.get('Europe/London')
|
1249
|
-
|
1250
|
-
assert_equal('BST', tz.strftime('%Z',
|
1251
|
-
assert_equal('
|
1252
|
-
assert_equal('
|
1256
|
+
dt = DateTime.new(2006, 7, 15, 22, 12, 2)
|
1257
|
+
assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', dt))
|
1258
|
+
assert_equal('BST', tz.strftime('%Z', dt))
|
1259
|
+
assert_equal('%ZBST', tz.strftime('%%Z%Z', dt))
|
1260
|
+
assert_equal('BST BST', tz.strftime('%Z %Z', dt))
|
1261
|
+
assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', dt))
|
1262
|
+
assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', dt))
|
1253
1263
|
end
|
1254
1264
|
|
1255
1265
|
def test_strftime_time
|
1256
1266
|
tz = Timezone.get('Europe/London')
|
1257
|
-
|
1258
|
-
assert_equal('BST', tz.strftime('%Z',
|
1259
|
-
assert_equal('
|
1260
|
-
assert_equal('
|
1267
|
+
t = Time.utc(2006, 7, 15, 22, 12, 2)
|
1268
|
+
assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', t))
|
1269
|
+
assert_equal('BST', tz.strftime('%Z', t))
|
1270
|
+
assert_equal('%ZBST', tz.strftime('%%Z%Z', t))
|
1271
|
+
assert_equal('BST BST', tz.strftime('%Z %Z', t))
|
1272
|
+
assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', t))
|
1273
|
+
assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', t))
|
1261
1274
|
end
|
1262
1275
|
|
1263
1276
|
def test_strftime_int
|
1264
1277
|
tz = Timezone.get('Europe/London')
|
1265
|
-
|
1266
|
-
assert_equal('BST', tz.strftime('%Z',
|
1267
|
-
assert_equal('
|
1268
|
-
assert_equal('
|
1278
|
+
i = Time.utc(2006, 7, 15, 22, 12, 2).to_i
|
1279
|
+
assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', i))
|
1280
|
+
assert_equal('BST', tz.strftime('%Z', i))
|
1281
|
+
assert_equal('%ZBST', tz.strftime('%%Z%Z', i))
|
1282
|
+
assert_equal('BST BST', tz.strftime('%Z %Z', i))
|
1283
|
+
assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', i))
|
1284
|
+
assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', i))
|
1269
1285
|
end
|
1270
1286
|
|
1271
1287
|
def test_get_missing_data_source
|
data/test/tc_timezone_proxy.rb
CHANGED
@@ -5,45 +5,59 @@ include TZInfo
|
|
5
5
|
class TCTimezoneProxy < Minitest::Test
|
6
6
|
def test_not_exist
|
7
7
|
proxy = TimezoneProxy.new('Nothing/Special')
|
8
|
+
t = Time.utc(2006,1,1,0,0,0)
|
8
9
|
assert_equal('Nothing/Special', proxy.identifier)
|
9
|
-
|
10
|
+
assert_equal('Nothing/Special', proxy.name)
|
11
|
+
assert_equal('Nothing - Special', proxy.friendly_identifier)
|
12
|
+
assert_equal('Nothing - Special', proxy.to_s)
|
13
|
+
|
14
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.canonical_identifier }
|
15
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.canonical_zone }
|
10
16
|
assert_raises(InvalidTimezoneIdentifier) { proxy.current_period }
|
11
17
|
assert_raises(InvalidTimezoneIdentifier) { proxy.current_period_and_time }
|
12
18
|
assert_raises(InvalidTimezoneIdentifier) { proxy.current_time_and_period }
|
13
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.
|
14
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.
|
15
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.
|
16
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.period_for_local(
|
17
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.
|
18
|
-
assert_raises(InvalidTimezoneIdentifier) { proxy.
|
19
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.local_to_utc(t) }
|
20
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.now }
|
21
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.offsets_up_to(t) }
|
22
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.period_for_local(t) }
|
23
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.period_for_utc(t) }
|
24
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.periods_for_local(t) }
|
25
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.strftime('%Z', t) }
|
26
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.transitions_up_to(t) }
|
27
|
+
assert_raises(InvalidTimezoneIdentifier) { proxy.utc_to_local(t) }
|
19
28
|
end
|
20
29
|
|
21
30
|
def test_valid
|
22
31
|
proxy = TimezoneProxy.new('Europe/London')
|
23
|
-
|
24
|
-
|
25
|
-
|
32
|
+
real = Timezone.get('Europe/London')
|
33
|
+
|
34
|
+
t1 = Time.utc(2005,8,1,0,0,0)
|
35
|
+
t2 = Time.utc(2004,8,1,0,0,0)
|
36
|
+
|
37
|
+
assert_equal(real.canonical_identifier, proxy.canonical_identifier)
|
38
|
+
assert_same(real.canonical_zone, proxy.canonical_zone)
|
26
39
|
assert_nothing_raised { proxy.current_period }
|
27
40
|
assert_nothing_raised { proxy.current_period_and_time }
|
28
41
|
assert_nothing_raised { proxy.current_time_and_period }
|
29
|
-
|
30
|
-
real = Timezone.get('Europe/London')
|
31
|
-
|
32
|
-
assert_equal(real.utc_to_local(DateTime.new(2005,8,1,0,0,0)), proxy.utc_to_local(DateTime.new(2005,8,1,0,0,0)))
|
33
|
-
assert_equal(real.local_to_utc(DateTime.new(2005,8,1,0,0,0)), proxy.local_to_utc(DateTime.new(2005,8,1,0,0,0)))
|
34
|
-
assert_equal(real.period_for_utc(DateTime.new(2005,8,1,0,0,0)), proxy.period_for_utc(DateTime.new(2005,8,1,0,0,0)))
|
35
|
-
assert_equal(real.period_for_local(DateTime.new(2005,8,1,0,0,0)), proxy.period_for_local(DateTime.new(2005,8,1,0,0,0)))
|
36
|
-
assert_equal(real.identifier, proxy.identifier)
|
37
|
-
assert_equal(real.name, proxy.name)
|
38
|
-
assert_equal(real.to_s, proxy.to_s)
|
39
42
|
assert_equal(real.friendly_identifier(true), proxy.friendly_identifier(true))
|
40
43
|
assert_equal(real.friendly_identifier(false), proxy.friendly_identifier(false))
|
41
44
|
assert_equal(real.friendly_identifier, proxy.friendly_identifier)
|
42
|
-
assert_equal(real.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
assert_equal(real.identifier, proxy.identifier)
|
46
|
+
assert_equal(real.local_to_utc(t1), proxy.local_to_utc(t1))
|
47
|
+
assert_equal(real.name, proxy.name)
|
48
|
+
assert_nothing_raised { proxy.now }
|
49
|
+
assert_equal(real.offsets_up_to(t1), proxy.offsets_up_to(t1))
|
50
|
+
assert_equal(real.offsets_up_to(t1, t2), proxy.offsets_up_to(t1, t2))
|
51
|
+
assert_equal(real.period_for_local(t1), proxy.period_for_local(t1))
|
52
|
+
assert_equal(real.period_for_utc(t1), proxy.period_for_utc(t1))
|
53
|
+
assert_equal(real.periods_for_local(t1), proxy.periods_for_local(t1))
|
54
|
+
assert_equal(real.strftime('%Z', t1), proxy.strftime('%Z', t1))
|
55
|
+
assert_equal(real.to_s, proxy.to_s)
|
56
|
+
assert_equal(real.transitions_up_to(t1), proxy.transitions_up_to(t1))
|
57
|
+
assert_equal(real.transitions_up_to(t1, t2), proxy.transitions_up_to(t1, t2))
|
58
|
+
assert_equal(real.utc_to_local(t1), proxy.utc_to_local(t1))
|
59
|
+
|
60
|
+
|
47
61
|
assert(real == proxy)
|
48
62
|
assert(proxy == real)
|
49
63
|
assert_equal(0, real <=> proxy)
|
@@ -395,6 +395,41 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
395
395
|
end
|
396
396
|
end
|
397
397
|
|
398
|
+
def test_load_timezone_info_ignored_timeconfig_symlink
|
399
|
+
# Slackware includes a symlink named timeconfig that points at /usr/sbin/timeconfig.
|
400
|
+
|
401
|
+
Dir.mktmpdir('tzinfo_test_target') do |target_dir|
|
402
|
+
target_path = File.join(target_dir, 'timeconfig')
|
403
|
+
|
404
|
+
File.open(target_path, 'w') do |f|
|
405
|
+
f.write("#!/bin/sh\n")
|
406
|
+
f.write("#\n")
|
407
|
+
f.write('# timeconfig Slackware Linux timezone configuration utility.\n')
|
408
|
+
end
|
409
|
+
|
410
|
+
Dir.mktmpdir('tzinfo_test') do |dir|
|
411
|
+
FileUtils.touch(File.join(dir, 'zone.tab'))
|
412
|
+
FileUtils.touch(File.join(dir, 'iso3166.tab'))
|
413
|
+
FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
|
414
|
+
|
415
|
+
symlink_path = File.join(dir, 'timeconfig')
|
416
|
+
begin
|
417
|
+
FileUtils.ln_s(target_path, symlink_path)
|
418
|
+
rescue NotImplementedError, Errno::EACCES
|
419
|
+
# Symlinks not supported on this platform, or permission denied
|
420
|
+
# (administrative rights are required on Windows). Copy instead.
|
421
|
+
FileUtils.cp(target_path, symlink_path)
|
422
|
+
end
|
423
|
+
|
424
|
+
data_source = ZoneinfoDataSource.new(dir)
|
425
|
+
|
426
|
+
assert_raises(InvalidTimezoneIdentifier) do
|
427
|
+
data_source.load_timezone_info('timeconfig')
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
398
433
|
def test_load_timezone_info_nil
|
399
434
|
assert_raises(InvalidTimezoneIdentifier) do
|
400
435
|
@data_source.load_timezone_info(nil)
|
@@ -453,8 +488,9 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
453
488
|
|
454
489
|
begin
|
455
490
|
FileUtils.ln_s(outside_file, file)
|
456
|
-
rescue NotImplementedError
|
457
|
-
# Symlinks not supported on this platform
|
491
|
+
rescue NotImplementedError, Errno::EACCES
|
492
|
+
# Symlinks not supported on this platform, or permission denied
|
493
|
+
# (administrative rights are required on Windows). Skip test.
|
458
494
|
return
|
459
495
|
end
|
460
496
|
|
@@ -478,8 +514,9 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
478
514
|
|
479
515
|
begin
|
480
516
|
FileUtils.ln_s(File.join(File.expand_path(dir), 'EST'), link)
|
481
|
-
rescue NotImplementedError
|
482
|
-
# Symlinks not supported on this platform
|
517
|
+
rescue NotImplementedError, Errno::EACCES
|
518
|
+
# Symlinks not supported on this platform, or permission denied
|
519
|
+
# (administrative rights are required on Windows). Skip test.
|
483
520
|
return
|
484
521
|
end
|
485
522
|
|
@@ -505,8 +542,9 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
505
542
|
|
506
543
|
begin
|
507
544
|
FileUtils.ln_s('../outside', link)
|
508
|
-
rescue NotImplementedError
|
509
|
-
# Symlinks not supported on this platform
|
545
|
+
rescue NotImplementedError, Errno::EACCES
|
546
|
+
# Symlinks not supported on this platform, or permission denied
|
547
|
+
# (administrative rights are required on Windows). Skip test.
|
510
548
|
return
|
511
549
|
end
|
512
550
|
|
@@ -541,8 +579,9 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
541
579
|
subdir_link = File.join(subdir, 'Link')
|
542
580
|
begin
|
543
581
|
FileUtils.ln_s('../Subdir/EST', subdir_link)
|
544
|
-
rescue NotImplementedError
|
545
|
-
# Symlinks not supported on this platform
|
582
|
+
rescue NotImplementedError, Errno::EACCES
|
583
|
+
# Symlinks not supported on this platform, or permission denied
|
584
|
+
# (administrative rights are required on Windows). Skip test.
|
546
585
|
return
|
547
586
|
end
|
548
587
|
|
@@ -613,7 +652,7 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
613
652
|
|
614
653
|
def test_load_timezone_info_tainted
|
615
654
|
safe_test do
|
616
|
-
identifier = 'Europe/Amsterdam'.taint
|
655
|
+
identifier = 'Europe/Amsterdam'.dup.taint
|
617
656
|
assert(identifier.tainted?)
|
618
657
|
info = @data_source.load_timezone_info(identifier)
|
619
658
|
assert_equal('Europe/Amsterdam', info.identifier)
|
@@ -623,7 +662,7 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
623
662
|
|
624
663
|
def test_load_timezone_info_tainted_and_frozen
|
625
664
|
safe_test do
|
626
|
-
info = @data_source.load_timezone_info('Europe/Amsterdam'.taint.freeze)
|
665
|
+
info = @data_source.load_timezone_info('Europe/Amsterdam'.dup.taint.freeze)
|
627
666
|
assert_equal('Europe/Amsterdam', info.identifier)
|
628
667
|
end
|
629
668
|
end
|
@@ -653,11 +692,11 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
653
692
|
|
654
693
|
entries = entries.collect {|file| file[directory.length + File::SEPARATOR.length, file.length - directory.length - File::SEPARATOR.length]}
|
655
694
|
|
656
|
-
# Exclude right (with leapseconds) and posix (copy) directories; .tab files; localtime
|
695
|
+
# Exclude right (with leapseconds) and posix (copy) directories; .tab files; localtime and posixrules files.
|
657
696
|
entries = entries.select do |file|
|
658
697
|
file !~ /\A(posix|right)\// &&
|
659
698
|
file !~ /\.tab\z/ &&
|
660
|
-
!%w(localtime posixrules
|
699
|
+
!%w(localtime posixrules).include?(file)
|
661
700
|
end
|
662
701
|
|
663
702
|
entries.sort
|
@@ -714,6 +753,38 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
714
753
|
end
|
715
754
|
end
|
716
755
|
|
756
|
+
def test_timezone_identifiers_ignored_timeconfig_symlink
|
757
|
+
# Slackware includes a symlink named timeconfig that points at /usr/sbin/timeconfig.
|
758
|
+
|
759
|
+
Dir.mktmpdir('tzinfo_test_target') do |target_dir|
|
760
|
+
target_path = File.join(target_dir, 'timeconfig')
|
761
|
+
|
762
|
+
File.open(target_path, 'w') do |f|
|
763
|
+
f.write("#!/bin/sh\n")
|
764
|
+
f.write("#\n")
|
765
|
+
f.write('# timeconfig Slackware Linux timezone configuration utility.\n')
|
766
|
+
end
|
767
|
+
|
768
|
+
Dir.mktmpdir('tzinfo_test') do |dir|
|
769
|
+
FileUtils.touch(File.join(dir, 'zone.tab'))
|
770
|
+
FileUtils.touch(File.join(dir, 'iso3166.tab'))
|
771
|
+
FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
|
772
|
+
|
773
|
+
symlink_path = File.join(dir, 'timeconfig')
|
774
|
+
begin
|
775
|
+
FileUtils.ln_s(target_path, symlink_path)
|
776
|
+
rescue NotImplementedError, Errno::EACCES
|
777
|
+
# Symlinks not supported on this platform, or permission denied
|
778
|
+
# (administrative rights are required on Windows). Copy instead.
|
779
|
+
FileUtils.cp(target_path, symlink_path)
|
780
|
+
end
|
781
|
+
|
782
|
+
data_source = ZoneinfoDataSource.new(dir)
|
783
|
+
assert_array_same_items(['EST'], data_source.timezone_identifiers)
|
784
|
+
end
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
717
788
|
def test_timezone_identifiers_ignored_src_directory
|
718
789
|
# Solaris includes a src directory containing the source timezone data files
|
719
790
|
# from the tzdata distribution. These should be ignored.
|
@@ -768,7 +839,7 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
768
839
|
|
769
840
|
def test_load_country_info_tainted
|
770
841
|
safe_test do
|
771
|
-
code = 'NL'.taint
|
842
|
+
code = 'NL'.dup.taint
|
772
843
|
assert(code.tainted?)
|
773
844
|
info = @data_source.load_country_info(code)
|
774
845
|
assert_equal('NL', info.code)
|
@@ -778,7 +849,7 @@ class TCZoneinfoDataSource < Minitest::Test
|
|
778
849
|
|
779
850
|
def test_load_country_info_tainted_and_frozen
|
780
851
|
safe_test do
|
781
|
-
info = @data_source.load_country_info('NL'.taint.freeze)
|
852
|
+
info = @data_source.load_country_info('NL'.dup.taint.freeze)
|
782
853
|
assert_equal('NL', info.code)
|
783
854
|
end
|
784
855
|
end
|
@@ -286,6 +286,17 @@ class TCZoneinfoTimezoneInfo < Minitest::Test
|
|
286
286
|
end
|
287
287
|
end
|
288
288
|
|
289
|
+
def test_load_no_offsets
|
290
|
+
offsets = []
|
291
|
+
transitions = [{:at => Time.utc(2000, 12, 31), :offset_index => 0}]
|
292
|
+
|
293
|
+
tzif_test(offsets, transitions) do |path, format|
|
294
|
+
assert_raises(InvalidZoneinfoFile) do
|
295
|
+
ZoneinfoTimezoneInfo.new('Zone', path)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
289
300
|
def test_load_invalid_offset_index
|
290
301
|
offsets = [{:gmtoff => -0, :isdst => false, :abbrev => 'LMT'}]
|
291
302
|
transitions = [{:at => Time.utc(2000, 12, 31), :offset_index => 2}]
|
@@ -707,27 +718,39 @@ class TCZoneinfoTimezoneInfo < Minitest::Test
|
|
707
718
|
end
|
708
719
|
end
|
709
720
|
|
710
|
-
def
|
721
|
+
def test_load_starts_only_dst_transition_with_lmt
|
711
722
|
# The zoneinfo files don't include the offset from standard time, so this
|
712
723
|
# has to be derived by looking at changes in the total UTC offset.
|
713
|
-
|
714
|
-
# If there are no changes in the UTC offset (ignoring the first offset,
|
715
|
-
# which is usually local mean time), then a value of 1 hour is used as the
|
716
|
-
# standard time offset.
|
717
|
-
|
724
|
+
|
718
725
|
offsets = [
|
719
726
|
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
720
|
-
{:gmtoff => 7200, :isdst => true, :abbrev => '
|
721
|
-
|
722
|
-
transitions = [
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
assert_period(:
|
730
|
-
|
727
|
+
{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
|
728
|
+
|
729
|
+
transitions = [{:at => Time.utc(2000, 1, 1), :offset_index => 1}]
|
730
|
+
|
731
|
+
tzif_test(offsets, transitions) do |path, format|
|
732
|
+
info = ZoneinfoTimezoneInfo.new('Zone/OnlyDST', path)
|
733
|
+
assert_equal('Zone/OnlyDST', info.identifier)
|
734
|
+
|
735
|
+
assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
736
|
+
assert_period(:XDT, 3542, 3658, true, Time.utc(2000, 1, 1), nil, info)
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
def test_load_starts_only_dst_transition_without_lmt
|
741
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
742
|
+
# has to be derived by looking at changes in the total UTC offset.
|
743
|
+
|
744
|
+
offsets = [{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
|
745
|
+
|
746
|
+
transitions = [{:at => Time.utc(2000, 1, 1), :offset_index => 0}]
|
747
|
+
|
748
|
+
tzif_test(offsets, transitions) do |path, format|
|
749
|
+
info = ZoneinfoTimezoneInfo.new('Zone/OnlyDST', path)
|
750
|
+
assert_equal('Zone/OnlyDST', info.identifier)
|
751
|
+
|
752
|
+
assert_period(:XDT, 3600, 3600, true, nil, Time.utc(2000, 1, 1), info)
|
753
|
+
assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 1, 1), nil, info)
|
731
754
|
end
|
732
755
|
end
|
733
756
|
|
@@ -756,6 +779,297 @@ class TCZoneinfoTimezoneInfo < Minitest::Test
|
|
756
779
|
assert_period(:XDT, 0, 3600, true, Time.utc(2000, 2, 1), nil, info)
|
757
780
|
end
|
758
781
|
end
|
782
|
+
|
783
|
+
def test_load_apia_international_dateline_change
|
784
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
785
|
+
# has to be derived by looking at changes in the total UTC offset.
|
786
|
+
|
787
|
+
# Pacific/Apia moved across the International Date Line whilst observing
|
788
|
+
# daylight savings time.
|
789
|
+
|
790
|
+
offsets = [
|
791
|
+
{:gmtoff => 45184, :isdst => false, :abbrev => 'LMT'},
|
792
|
+
{:gmtoff => -39600, :isdst => false, :abbrev => '-11'},
|
793
|
+
{:gmtoff => -36000, :isdst => true, :abbrev => '-10'},
|
794
|
+
{:gmtoff => 50400, :isdst => true, :abbrev => '+14'},
|
795
|
+
{:gmtoff => 46800, :isdst => false, :abbrev => '+13'}]
|
796
|
+
|
797
|
+
transitions = [
|
798
|
+
{:at => Time.utc(2011, 4, 2, 14, 0, 0), :offset_index => 1},
|
799
|
+
{:at => Time.utc(2011, 9, 24, 14, 0, 0), :offset_index => 2},
|
800
|
+
{:at => Time.utc(2011, 12, 30, 10, 0, 0), :offset_index => 3},
|
801
|
+
{:at => Time.utc(2012, 3, 31, 14, 0, 0), :offset_index => 4}]
|
802
|
+
|
803
|
+
tzif_test(offsets, transitions) do |path, format|
|
804
|
+
info = ZoneinfoTimezoneInfo.new('Test/Pacific/Apia', path)
|
805
|
+
assert_equal('Test/Pacific/Apia', info.identifier)
|
806
|
+
|
807
|
+
assert_period( :LMT, 45184, 0, false, nil, Time.utc(2011, 4, 2, 14, 0, 0), info)
|
808
|
+
assert_period(:'-11', -39600, 0, false, Time.utc(2011, 4, 2, 14, 0, 0), Time.utc(2011, 9, 24, 14, 0, 0), info)
|
809
|
+
assert_period(:'-10', -39600, 3600, true, Time.utc(2011, 9, 24, 14, 0, 0), Time.utc(2011, 12, 30, 10, 0, 0), info)
|
810
|
+
assert_period(:'+14', 46800, 3600, true, Time.utc(2011, 12, 30, 10, 0, 0), Time.utc(2012, 3, 31, 14, 0, 0), info)
|
811
|
+
assert_period(:'+13', 46800, 0, false, Time.utc(2012, 3, 31, 14, 0, 0), nil, info)
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
815
|
+
def test_load_offset_split_for_different_utc_offset
|
816
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
817
|
+
# has to be derived by looking at changes in the total UTC offset.
|
818
|
+
|
819
|
+
offsets = [
|
820
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
821
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
822
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
823
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
|
824
|
+
|
825
|
+
transitions = [
|
826
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 1},
|
827
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
828
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 1},
|
829
|
+
{:at => Time.utc(2000, 4, 1), :offset_index => 2},
|
830
|
+
{:at => Time.utc(2000, 5, 1), :offset_index => 3},
|
831
|
+
{:at => Time.utc(2000, 6, 1), :offset_index => 2},
|
832
|
+
{:at => Time.utc(2000, 7, 1), :offset_index => 1},
|
833
|
+
{:at => Time.utc(2000, 8, 1), :offset_index => 3},
|
834
|
+
{:at => Time.utc(2000, 9, 1), :offset_index => 1},
|
835
|
+
{:at => Time.utc(2000, 10, 1), :offset_index => 2},
|
836
|
+
{:at => Time.utc(2000, 11, 1), :offset_index => 3},
|
837
|
+
{:at => Time.utc(2000, 12, 1), :offset_index => 2}]
|
838
|
+
|
839
|
+
# XDT will be split and defined according to its surrounding standard time
|
840
|
+
# offsets.
|
841
|
+
|
842
|
+
tzif_test(offsets, transitions) do |path, format|
|
843
|
+
info = ZoneinfoTimezoneInfo.new('Zone/SplitUtcOffset', path)
|
844
|
+
assert_equal('Zone/SplitUtcOffset', info.identifier)
|
845
|
+
|
846
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
847
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
848
|
+
assert_period( :XDT, 3600, 7200, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
849
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
|
850
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
|
851
|
+
assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
|
852
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 6, 1), Time.utc(2000, 7, 1), info)
|
853
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 7, 1), Time.utc(2000, 8, 1), info)
|
854
|
+
assert_period( :XDT, 3600, 7200, true, Time.utc(2000, 8, 1), Time.utc(2000, 9, 1), info)
|
855
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 9, 1), Time.utc(2000, 10, 1), info)
|
856
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 10, 1), Time.utc(2000, 11, 1), info)
|
857
|
+
assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 11, 1), Time.utc(2000, 12, 1), info)
|
858
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 12, 1), nil, info)
|
859
|
+
|
860
|
+
1.upto(6) do |i|
|
861
|
+
assert_same(info.period_for_utc(Time.utc(2000, i, 1)).offset, info.period_for_utc(Time.utc(2000, i + 6, 1)).offset)
|
862
|
+
end
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
def test_load_offset_utc_offset_taken_from_minimum_difference_minimum_after
|
867
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
868
|
+
# has to be derived by looking at changes in the total UTC offset.
|
869
|
+
|
870
|
+
offsets = [
|
871
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
872
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
873
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
874
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
|
875
|
+
|
876
|
+
transitions = [
|
877
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 1},
|
878
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
879
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 2}]
|
880
|
+
|
881
|
+
# XDT should use the closest utc_offset (7200) (and not an equivalent
|
882
|
+
# utc_offset of 3600 and std_offset of 7200).
|
883
|
+
|
884
|
+
tzif_test(offsets, transitions) do |path, format|
|
885
|
+
info = ZoneinfoTimezoneInfo.new('Zone/MinimumUtcOffset', path)
|
886
|
+
assert_equal('Zone/MinimumUtcOffset', info.identifier)
|
887
|
+
|
888
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
889
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
890
|
+
assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
891
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
def test_load_offset_utc_offset_taken_from_minimum_difference_minimum_before
|
896
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
897
|
+
# has to be derived by looking at changes in the total UTC offset.
|
898
|
+
|
899
|
+
offsets = [
|
900
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
901
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
902
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
903
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
|
904
|
+
|
905
|
+
transitions = [
|
906
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 2},
|
907
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
908
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 1}]
|
909
|
+
|
910
|
+
# XDT should use the closest utc_offset (7200) (and not an equivalent
|
911
|
+
# utc_offset of 3600 and std_offset of 7200).
|
912
|
+
|
913
|
+
tzif_test(offsets, transitions) do |path, format|
|
914
|
+
info = ZoneinfoTimezoneInfo.new('Zone/MinimumUtcOffset', path)
|
915
|
+
assert_equal('Zone/MinimumUtcOffset', info.identifier)
|
916
|
+
|
917
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
918
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
919
|
+
assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
920
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
def test_load_offset_does_not_use_equal_utc_total_offset_equal_after
|
925
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
926
|
+
# has to be derived by looking at changes in the total UTC offset.
|
927
|
+
|
928
|
+
offsets = [
|
929
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
930
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
931
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
932
|
+
{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
|
933
|
+
|
934
|
+
transitions = [
|
935
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 1},
|
936
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
937
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 2}]
|
938
|
+
|
939
|
+
# XDT will be based on the utc_offset of XST1 even though XST2 has an
|
940
|
+
# equivalent (or greater) utc_total_offset.
|
941
|
+
|
942
|
+
tzif_test(offsets, transitions) do |path, format|
|
943
|
+
info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetEqual', path)
|
944
|
+
assert_equal('Zone/UtcOffsetEqual', info.identifier)
|
945
|
+
|
946
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
947
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
948
|
+
assert_period( :XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
949
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
def test_load_offset_does_not_use_equal_utc_total_offset_equal_before
|
954
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
955
|
+
# has to be derived by looking at changes in the total UTC offset.
|
956
|
+
|
957
|
+
offsets = [
|
958
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
959
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
960
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
961
|
+
{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
|
962
|
+
|
963
|
+
transitions = [
|
964
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 2},
|
965
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
966
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 1}]
|
967
|
+
|
968
|
+
# XDT will be based on the utc_offset of XST1 even though XST2 has an
|
969
|
+
# equivalent (or greater) utc_total_offset.
|
970
|
+
|
971
|
+
tzif_test(offsets, transitions) do |path, format|
|
972
|
+
info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetEqual', path)
|
973
|
+
assert_equal('Zone/UtcOffsetEqual', info.identifier)
|
974
|
+
|
975
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
976
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
977
|
+
assert_period( :XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
978
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
|
979
|
+
end
|
980
|
+
end
|
981
|
+
|
982
|
+
def test_load_offset_both_adjacent_non_dst_equal_utc_total_offset
|
983
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
984
|
+
# has to be derived by looking at changes in the total UTC offset.
|
985
|
+
|
986
|
+
offsets = [
|
987
|
+
{:gmtoff => 7142, :isdst => false, :abbrev => 'LMT'},
|
988
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST'},
|
989
|
+
{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
|
990
|
+
|
991
|
+
transitions = [
|
992
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 1},
|
993
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 2},
|
994
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 1}]
|
995
|
+
|
996
|
+
# XDT will just assume an std_offset of +1 hour and calculate the utc_offset
|
997
|
+
# from utc_total_offset - std_offset.
|
998
|
+
|
999
|
+
tzif_test(offsets, transitions) do |path, format|
|
1000
|
+
info = ZoneinfoTimezoneInfo.new('Zone/AdjacentEqual', path)
|
1001
|
+
assert_equal('Zone/AdjacentEqual', info.identifier)
|
1002
|
+
|
1003
|
+
assert_period(:LMT, 7142, 0, false, nil, Time.utc(2000, 1, 1), info)
|
1004
|
+
assert_period(:XST, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
1005
|
+
assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
1006
|
+
assert_period(:XST, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def test_load_offset_utc_offset_preserved_from_next
|
1011
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
1012
|
+
# has to be derived by looking at changes in the total UTC offset.
|
1013
|
+
|
1014
|
+
offsets = [
|
1015
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
1016
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
1017
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
1018
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT1'},
|
1019
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT2'}]
|
1020
|
+
|
1021
|
+
transitions = [
|
1022
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 1},
|
1023
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
1024
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 4},
|
1025
|
+
{:at => Time.utc(2000, 4, 1), :offset_index => 2}]
|
1026
|
+
|
1027
|
+
# Both XDT1 and XDT2 should both use the closest utc_offset (7200) (and not
|
1028
|
+
# an equivalent utc_offset of 3600 and std_offset of 7200).
|
1029
|
+
|
1030
|
+
tzif_test(offsets, transitions) do |path, format|
|
1031
|
+
info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetPreserved', path)
|
1032
|
+
assert_equal('Zone/UtcOffsetPreserved', info.identifier)
|
1033
|
+
|
1034
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
1035
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
1036
|
+
assert_period(:XDT1, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
1037
|
+
assert_period(:XDT2, 7200, 3600, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
|
1038
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 4, 1), nil, info)
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
def test_load_offset_utc_offset_preserved_from_previous
|
1043
|
+
# The zoneinfo files don't include the offset from standard time, so this
|
1044
|
+
# has to be derived by looking at changes in the total UTC offset.
|
1045
|
+
|
1046
|
+
offsets = [
|
1047
|
+
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
1048
|
+
{:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
|
1049
|
+
{:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
|
1050
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT1'},
|
1051
|
+
{:gmtoff => 10800, :isdst => true, :abbrev => 'XDT2'}]
|
1052
|
+
|
1053
|
+
transitions = [
|
1054
|
+
{:at => Time.utc(2000, 1, 1), :offset_index => 2},
|
1055
|
+
{:at => Time.utc(2000, 2, 1), :offset_index => 3},
|
1056
|
+
{:at => Time.utc(2000, 3, 1), :offset_index => 4},
|
1057
|
+
{:at => Time.utc(2000, 4, 1), :offset_index => 1}]
|
1058
|
+
|
1059
|
+
# Both XDT1 and XDT2 should both use the closest utc_offset (7200) (and not
|
1060
|
+
# an equivalent utc_offset of 3600 and std_offset of 7200).
|
1061
|
+
|
1062
|
+
tzif_test(offsets, transitions) do |path, format|
|
1063
|
+
info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetPreserved', path)
|
1064
|
+
assert_equal('Zone/UtcOffsetPreserved', info.identifier)
|
1065
|
+
|
1066
|
+
assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
|
1067
|
+
assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
|
1068
|
+
assert_period(:XDT1, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
|
1069
|
+
assert_period(:XDT2, 7200, 3600, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
|
1070
|
+
assert_period(:XST1, 3600, 0, false, Time.utc(2000, 4, 1), nil, info)
|
1071
|
+
end
|
1072
|
+
end
|
759
1073
|
|
760
1074
|
def test_load_in_safe_mode
|
761
1075
|
offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
|