tzinfo 1.0.1 → 1.1.0
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/.yardopts +6 -0
- data/{CHANGES → CHANGES.md} +121 -50
- data/{README → README.md} +48 -34
- data/Rakefile +45 -22
- data/lib/tzinfo.rb +7 -2
- data/lib/tzinfo/country.rb +23 -1
- data/lib/tzinfo/country_index_definition.rb +6 -1
- data/lib/tzinfo/country_timezone.rb +9 -1
- data/lib/tzinfo/data_source.rb +26 -5
- data/lib/tzinfo/data_timezone.rb +30 -2
- data/lib/tzinfo/data_timezone_info.rb +26 -0
- data/lib/tzinfo/info_timezone.rb +3 -1
- data/lib/tzinfo/linked_timezone.rb +30 -1
- data/lib/tzinfo/offset_rationals.rb +5 -3
- data/lib/tzinfo/ruby_core_support.rb +2 -0
- data/lib/tzinfo/ruby_country_info.rb +14 -0
- data/lib/tzinfo/ruby_data_source.rb +5 -0
- data/lib/tzinfo/time_or_datetime.rb +16 -1
- data/lib/tzinfo/timezone.rb +107 -5
- data/lib/tzinfo/timezone_definition.rb +5 -1
- data/lib/tzinfo/timezone_index_definition.rb +7 -1
- data/lib/tzinfo/{timezone_offset_info.rb → timezone_offset.rb} +12 -10
- data/lib/tzinfo/timezone_period.rb +19 -15
- data/lib/tzinfo/timezone_proxy.rb +5 -1
- data/lib/tzinfo/timezone_transition.rb +136 -0
- data/lib/tzinfo/{timezone_transition_info.rb → timezone_transition_definition.rb} +21 -57
- data/lib/tzinfo/transition_data_timezone_info.rb +81 -8
- data/lib/tzinfo/zoneinfo_country_info.rb +7 -0
- data/lib/tzinfo/zoneinfo_data_source.rb +104 -57
- data/lib/tzinfo/zoneinfo_timezone_info.rb +18 -10
- data/test/tc_country.rb +39 -1
- data/test/tc_data_timezone.rb +28 -5
- data/test/tc_linked_timezone.rb +24 -3
- data/test/tc_ruby_data_source.rb +22 -2
- data/test/tc_time_or_datetime.rb +3 -3
- data/test/tc_timezone.rb +364 -117
- data/test/tc_timezone_london.rb +25 -0
- data/test/tc_timezone_melbourne.rb +24 -0
- data/test/tc_timezone_new_york.rb +24 -0
- data/test/{tc_timezone_offset_info.rb → tc_timezone_offset.rb} +27 -27
- data/test/tc_timezone_period.rb +113 -90
- data/test/tc_timezone_transition.rb +374 -0
- data/test/tc_timezone_transition_definition.rb +306 -0
- data/test/tc_transition_data_timezone_info.rb +143 -43
- data/test/tc_zoneinfo_data_source.rb +69 -5
- data/test/tc_zoneinfo_timezone_info.rb +63 -20
- data/test/test_utils.rb +27 -7
- data/tzinfo.gemspec +21 -0
- metadata +61 -38
- metadata.gz.sig +3 -0
- data/test/tc_timezone_transition_info.rb +0 -471
- data/test/zoneinfo/UTC +0 -0
- data/test/zoneinfo/localtime +0 -0
@@ -123,19 +123,19 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
123
123
|
dti.transition 2003, 2, :o2, Time.utc(2003, 2,1,1,0,0).to_i
|
124
124
|
dti.transition 2003, 3, :o3, Time.utc(2003, 3,1,1,0,0).to_i
|
125
125
|
|
126
|
-
o1 =
|
127
|
-
o2 =
|
128
|
-
o3 =
|
129
|
-
o4 =
|
130
|
-
|
131
|
-
t1 =
|
132
|
-
t2 =
|
133
|
-
t3 =
|
134
|
-
t4 =
|
135
|
-
t5 =
|
136
|
-
t6 =
|
137
|
-
t7 =
|
138
|
-
t8 =
|
126
|
+
o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
|
127
|
+
o2 = TimezoneOffset.new(-18000, 3600, :TESTD)
|
128
|
+
o3 = TimezoneOffset.new(-18000, 0, :TESTS)
|
129
|
+
o4 = TimezoneOffset.new(-21600, 3600, :TESTD)
|
130
|
+
|
131
|
+
t1 = TimezoneTransitionDefinition.new(o2, o1, Time.utc(2000, 4,1,1,0,0).to_i)
|
132
|
+
t2 = TimezoneTransitionDefinition.new(o3, o2, Time.utc(2000,10,1,1,0,0).to_i)
|
133
|
+
t3 = TimezoneTransitionDefinition.new(o2, o3, Time.utc(2001, 3,1,1,0,0).to_i)
|
134
|
+
t4 = TimezoneTransitionDefinition.new(o4, o2, Time.utc(2001, 4,1,1,0,0).to_i)
|
135
|
+
t5 = TimezoneTransitionDefinition.new(o3, o4, Time.utc(2001,10,1,1,0,0).to_i)
|
136
|
+
t6 = TimezoneTransitionDefinition.new(o3, o3, Time.utc(2002,10,1,1,0,0).to_i)
|
137
|
+
t7 = TimezoneTransitionDefinition.new(o2, o3, Time.utc(2003, 2,1,1,0,0).to_i)
|
138
|
+
t8 = TimezoneTransitionDefinition.new(o3, o2, Time.utc(2003, 3,1,1,0,0).to_i)
|
139
139
|
|
140
140
|
assert_equal(TimezonePeriod.new(nil, t1), dti.period_for_utc(DateTime.new(1960, 1,1,1, 0, 0)))
|
141
141
|
assert_equal(TimezonePeriod.new(nil, t1), dti.period_for_utc(DateTime.new(1999,12,1,0, 0, 0)))
|
@@ -165,7 +165,7 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
165
165
|
dti.offset :o1, -17900, 0, :TESTLMT
|
166
166
|
dti.offset :o2, -18000, 0, :TEST
|
167
167
|
|
168
|
-
o1 =
|
168
|
+
o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
|
169
169
|
|
170
170
|
assert_equal(TimezonePeriod.new(nil, nil, o1), dti.period_for_utc(DateTime.new(2005,1,1,0,0,0)))
|
171
171
|
assert_equal(TimezonePeriod.new(nil, nil, o1), dti.period_for_utc(Time.utc(2005,1,1,0,0,0)))
|
@@ -195,18 +195,18 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
195
195
|
dti.transition 2002, 10, :o3, 58861189, 24 # 2002,10,2,1,0,0
|
196
196
|
dti.transition 2003, 2, :o2, Time.utc(2003, 2,2,1,0,0).to_i
|
197
197
|
|
198
|
-
o1 =
|
199
|
-
o2 =
|
200
|
-
o3 =
|
201
|
-
o4 =
|
198
|
+
o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
|
199
|
+
o2 = TimezoneOffset.new(-18000, 3600, :TESTD)
|
200
|
+
o3 = TimezoneOffset.new(-18000, 0, :TESTS)
|
201
|
+
o4 = TimezoneOffset.new(-21600, 3600, :TESTD)
|
202
202
|
|
203
|
-
t1 =
|
204
|
-
t2 =
|
205
|
-
t3 =
|
206
|
-
t4 =
|
207
|
-
t5 =
|
208
|
-
t6 =
|
209
|
-
t7 =
|
203
|
+
t1 = TimezoneTransitionDefinition.new(o2, o1, Time.utc(2000, 4,2,1,0,0).to_i)
|
204
|
+
t2 = TimezoneTransitionDefinition.new(o3, o2, Time.utc(2000,10,2,1,0,0).to_i)
|
205
|
+
t3 = TimezoneTransitionDefinition.new(o2, o3, Time.utc(2001, 3,2,1,0,0).to_i)
|
206
|
+
t4 = TimezoneTransitionDefinition.new(o4, o2, Time.utc(2001, 4,2,1,0,0).to_i)
|
207
|
+
t5 = TimezoneTransitionDefinition.new(o3, o4, Time.utc(2001,10,2,1,0,0).to_i)
|
208
|
+
t6 = TimezoneTransitionDefinition.new(o3, o3, Time.utc(2002,10,2,1,0,0).to_i)
|
209
|
+
t7 = TimezoneTransitionDefinition.new(o2, o3, Time.utc(2003, 2,2,1,0,0).to_i)
|
210
210
|
|
211
211
|
|
212
212
|
assert_equal([TimezonePeriod.new(nil, t1)], dti.periods_for_local(DateTime.new(1960, 1, 1, 1, 0, 0)))
|
@@ -257,14 +257,14 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
257
257
|
dti.transition 1915, 8, :o3, 290485733, 120 # 1915, 8, 4,22,36,0
|
258
258
|
dti.transition 1916, 4, :o4, 29051813, 12 # 1916, 4,30,22, 0,0
|
259
259
|
|
260
|
-
o1 =
|
261
|
-
o2 =
|
262
|
-
o3 =
|
263
|
-
o4 =
|
260
|
+
o1 = TimezoneOffset.new(5040, 0, :LMT)
|
261
|
+
o2 = TimezoneOffset.new(5040, 0, :WMT)
|
262
|
+
o3 = TimezoneOffset.new(3600, 0, :CET)
|
263
|
+
o4 = TimezoneOffset.new(3600, 3600, :CEST)
|
264
264
|
|
265
|
-
t1 =
|
266
|
-
t2 =
|
267
|
-
t3 =
|
265
|
+
t1 = TimezoneTransitionDefinition.new(o2, o1, 288925853, 120)
|
266
|
+
t2 = TimezoneTransitionDefinition.new(o3, o2, 290485733, 120)
|
267
|
+
t3 = TimezoneTransitionDefinition.new(o4, o3, 29051813, 12)
|
268
268
|
|
269
269
|
assert_equal([TimezonePeriod.new(t1, t2),
|
270
270
|
TimezonePeriod.new(t2, t3)], dti.periods_for_local(DateTime.new(1915,8,4,23,40,0)))
|
@@ -277,10 +277,10 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
277
277
|
|
278
278
|
dti.transition 2000, 7, :o2, Time.utc(2000,7,1,0,0,0).to_i
|
279
279
|
|
280
|
-
o1 =
|
281
|
-
o2 =
|
280
|
+
o1 = TimezoneOffset.new(-3600, 0, :TESTD)
|
281
|
+
o2 = TimezoneOffset.new(-3600, 0, :TESTS)
|
282
282
|
|
283
|
-
t1 =
|
283
|
+
t1 = TimezoneTransitionDefinition.new(o2, o1, Time.utc(2000,7,1,0,0,0).to_i)
|
284
284
|
|
285
285
|
# 2000-07-01 00:00:00 UTC is 2000-06-30 23:00:00 UTC-1
|
286
286
|
# hence to find periods for local times between 2000-06-30 23:00:00
|
@@ -297,7 +297,7 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
297
297
|
dti.offset :o1, -17900, 0, :TESTLMT
|
298
298
|
dti.offset :o2, -18000, 0, :TEST
|
299
299
|
|
300
|
-
o1 =
|
300
|
+
o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
|
301
301
|
|
302
302
|
assert_equal([TimezonePeriod.new(nil, nil, o1)], dti.periods_for_local(DateTime.new(2005,1,1,0,0,0)))
|
303
303
|
assert_equal([TimezonePeriod.new(nil, nil, o1)], dti.periods_for_local(Time.utc(2005,1,1,0,0,0)))
|
@@ -312,6 +312,106 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
312
312
|
assert_raises(NoOffsetsDefined) { dti.periods_for_local(Time.utc(2005,1,1,0,0,0).to_i) }
|
313
313
|
end
|
314
314
|
|
315
|
+
def test_transitions_up_to
|
316
|
+
dti = TransitionDataTimezoneInfo.new('Test/Zone')
|
317
|
+
dti.offset :o1, -17900, 0, :TESTLMT
|
318
|
+
dti.offset :o2, -18000, 3600, :TESTD
|
319
|
+
dti.offset :o3, -18000, 0, :TESTS
|
320
|
+
dti.offset :o4, -21600, 3600, :TESTD
|
321
|
+
|
322
|
+
dti.transition 2010, 4, :o2, Time.utc(2010, 4,1,1,0,0).to_i
|
323
|
+
dti.transition 2010, 10, :o3, Time.utc(2010,10,1,1,0,0).to_i
|
324
|
+
dti.transition 2011, 3, :o2, 58934917, 24 # (2011, 3,1,1,0,0)
|
325
|
+
dti.transition 2011, 4, :o4, Time.utc(2011, 4,1,1,0,0).to_i, 58935661, 24
|
326
|
+
dti.transition 2011, 10, :o3, Time.utc(2011,10,1,1,0,0).to_i
|
327
|
+
|
328
|
+
o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
|
329
|
+
o2 = TimezoneOffset.new(-18000, 3600, :TESTD)
|
330
|
+
o3 = TimezoneOffset.new(-18000, 0, :TESTS)
|
331
|
+
o4 = TimezoneOffset.new(-21600, 3600, :TESTD)
|
332
|
+
|
333
|
+
t1 = TimezoneTransitionDefinition.new(o2, o1, Time.utc(2010, 4,1,1,0,0).to_i)
|
334
|
+
t2 = TimezoneTransitionDefinition.new(o3, o2, Time.utc(2010,10,1,1,0,0).to_i)
|
335
|
+
t3 = TimezoneTransitionDefinition.new(o2, o3, Time.utc(2011, 3,1,1,0,0).to_i)
|
336
|
+
t4 = TimezoneTransitionDefinition.new(o4, o2, Time.utc(2011, 4,1,1,0,0).to_i)
|
337
|
+
t5 = TimezoneTransitionDefinition.new(o3, o4, Time.utc(2011,10,1,1,0,0).to_i)
|
338
|
+
|
339
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2010,4,1,1,0,0)))
|
340
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2010,4,1,1,0,0), Time.utc(2000,1,1,0,0,0)))
|
341
|
+
assert_equal([t1], dti.transitions_up_to(Time.utc(2010,4,1,1,0,1)))
|
342
|
+
assert_equal([t1], dti.transitions_up_to(Time.utc(2010,4,1,1,0,1), Time.utc(2000,1,1,0,0,0)))
|
343
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(Time.utc(2011,4,1,1,0,1), Time.utc(2010,10,1,1,0,0)))
|
344
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(Time.utc(2011,10,1,1,0,0), Time.utc(2010,4,1,1,0,1)))
|
345
|
+
assert_equal([t3], dti.transitions_up_to(Time.utc(2011,4,1,1,0,0), Time.utc(2010,10,1,1,0,1)))
|
346
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2011,3,1,1,0,0), Time.utc(2010,10,1,1,0,1)))
|
347
|
+
assert_equal([t1,t2,t3,t4], dti.transitions_up_to(Time.utc(2011,10,1,1,0,0)))
|
348
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1)))
|
349
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,0,1)))
|
350
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1), Time.utc(2010,4,1,1,0,0)))
|
351
|
+
assert_equal([t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1), Time.utc(2010,4,1,1,0,1)))
|
352
|
+
assert_equal([t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1), Time.utc(2010,4,1,1,0,0,1)))
|
353
|
+
assert_equal([t5], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0), Time.utc(2011,10,1,1,0,0)))
|
354
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0), Time.utc(2011,10,1,1,0,1)))
|
355
|
+
|
356
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2010,4,1,1,0,0).to_i))
|
357
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2010,4,1,1,0,0).to_i, Time.utc(2000,1,1,0,0,0).to_i))
|
358
|
+
assert_equal([t1], dti.transitions_up_to(Time.utc(2010,4,1,1,0,1).to_i))
|
359
|
+
assert_equal([t1], dti.transitions_up_to(Time.utc(2010,4,1,1,0,1).to_i, Time.utc(2000,1,1,0,0,0).to_i))
|
360
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(Time.utc(2011,4,1,1,0,1).to_i, Time.utc(2010,10,1,1,0,0).to_i))
|
361
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(Time.utc(2011,10,1,1,0,0).to_i, Time.utc(2010,4,1,1,0,1).to_i))
|
362
|
+
assert_equal([t3], dti.transitions_up_to(Time.utc(2011,4,1,1,0,0).to_i, Time.utc(2010,10,1,1,0,1).to_i))
|
363
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2011,3,1,1,0,0).to_i, Time.utc(2010,10,1,1,0,1).to_i))
|
364
|
+
assert_equal([t1,t2,t3,t4], dti.transitions_up_to(Time.utc(2011,10,1,1,0,0).to_i))
|
365
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1).to_i))
|
366
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,0).to_i))
|
367
|
+
assert_equal([t2,t3,t4,t5], dti.transitions_up_to(Time.utc(2011,10,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,1).to_i))
|
368
|
+
assert_equal([t5], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0).to_i, Time.utc(2011,10,1,1,0,0).to_i))
|
369
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0).to_i, Time.utc(2011,10,1,1,0,1).to_i))
|
370
|
+
|
371
|
+
assert_equal([], dti.transitions_up_to(DateTime.new(2010,4,1,1,0,0)))
|
372
|
+
assert_equal([], dti.transitions_up_to(DateTime.new(2010,4,1,1,0,0), DateTime.new(2000,1,1,0,0,0)))
|
373
|
+
assert_equal([t1], dti.transitions_up_to(DateTime.new(2010,4,1,1,0,1)))
|
374
|
+
assert_equal([t1], dti.transitions_up_to(DateTime.new(2010,4,1,1,0,1), DateTime.new(2000,1,1,0,0,0)))
|
375
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(DateTime.new(2011,4,1,1,0,1), DateTime.new(2010,10,1,1,0,0)))
|
376
|
+
assert_equal([t2,t3,t4], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,0), DateTime.new(2010,4,1,1,0,1)))
|
377
|
+
assert_equal([t3], dti.transitions_up_to(DateTime.new(2011,4,1,1,0,0), DateTime.new(2010,10,1,1,0,1)))
|
378
|
+
assert_equal([], dti.transitions_up_to(DateTime.new(2011,3,1,1,0,0), DateTime.new(2010,10,1,1,0,1)))
|
379
|
+
assert_equal([t1,t2,t3,t4], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,0)))
|
380
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,1)))
|
381
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,Rational(1,1000000))))
|
382
|
+
assert_equal([t1,t2,t3,t4,t5], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,1), DateTime.new(2010,4,1,1,0,0)))
|
383
|
+
assert_equal([t2,t3,t4,t5], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,1), DateTime.new(2010,4,1,1,0,1)))
|
384
|
+
assert_equal([t2,t3,t4,t5], dti.transitions_up_to(DateTime.new(2011,10,1,1,0,1), DateTime.new(2010,4,1,1,0,Rational(1,1000000))))
|
385
|
+
assert_equal([t5], dti.transitions_up_to(DateTime.new(2015,1,1,0,0,0), DateTime.new(2011,10,1,1,0,0)))
|
386
|
+
assert_equal([], dti.transitions_up_to(DateTime.new(2015,1,1,0,0,0), DateTime.new(2011,10,1,1,0,1)))
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_transitions_up_to_no_transitions
|
390
|
+
dti = TransitionDataTimezoneInfo.new('Test/Zone')
|
391
|
+
dti.offset :o1, -17900, 0, :TESTLMT
|
392
|
+
|
393
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0)))
|
394
|
+
assert_equal([], dti.transitions_up_to(Time.utc(2015,1,1,0,0,0).to_i))
|
395
|
+
assert_equal([], dti.transitions_up_to(DateTime.new(2015,1,1,0,0,0)))
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_transitions_up_to_utc_to_not_greater_than_utc_from
|
399
|
+
dti = TransitionDataTimezoneInfo.new('Test/Zone')
|
400
|
+
dti.offset :o1, -17900, 0, :TESTLMT
|
401
|
+
|
402
|
+
assert_raises(ArgumentError) do
|
403
|
+
dti.transitions_up_to(Time.utc(2012,8,1,0,0,0), Time.utc(2013,8,1,0,0,0))
|
404
|
+
end
|
405
|
+
|
406
|
+
assert_raises(ArgumentError) do
|
407
|
+
dti.transitions_up_to(Time.utc(2012,8,1,0,0,0).to_i, Time.utc(2012,8,1,0,0,0).to_i)
|
408
|
+
end
|
409
|
+
|
410
|
+
assert_raises(ArgumentError) do
|
411
|
+
dti.transitions_up_to(DateTime.new(2012,8,1,0,0,0), DateTime.new(2012,8,1,0,0,0))
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
315
415
|
def test_datetime_and_timestamp_use
|
316
416
|
dti = TransitionDataTimezoneInfo.new('Test/Zone')
|
317
417
|
dti.offset :o1, 0, 0, :TESTS
|
@@ -323,23 +423,23 @@ class TCTransitionDataTimezoneInfo < Test::Unit::TestCase
|
|
323
423
|
dti.transition 2038, 1, :o1, 2147483648, 3328347557, 1350
|
324
424
|
|
325
425
|
if RubyCoreSupport.time_supports_negative && RubyCoreSupport.time_supports_64bit
|
326
|
-
assert(dti.period_for_utc(DateTime.new(1901,12,13,20,45,51)).
|
426
|
+
assert(dti.period_for_utc(DateTime.new(1901,12,13,20,45,51)).start_transition.at.eql?(TimeOrDateTime.new(-2147483649)))
|
327
427
|
else
|
328
|
-
assert(dti.period_for_utc(DateTime.new(1901,12,13,20,45,51)).
|
428
|
+
assert(dti.period_for_utc(DateTime.new(1901,12,13,20,45,51)).start_transition.at.eql?(TimeOrDateTime.new(DateTime.new(1901,12,13,20,45,51))))
|
329
429
|
end
|
330
430
|
|
331
431
|
if RubyCoreSupport.time_supports_negative
|
332
|
-
assert(dti.period_for_utc(DateTime.new(1969,12,31,23,59,59)).
|
432
|
+
assert(dti.period_for_utc(DateTime.new(1969,12,31,23,59,59)).start_transition.at.eql?(TimeOrDateTime.new(-1)))
|
333
433
|
else
|
334
|
-
assert(dti.period_for_utc(DateTime.new(1969,12,31,23,59,59)).
|
434
|
+
assert(dti.period_for_utc(DateTime.new(1969,12,31,23,59,59)).start_transition.at.eql?(TimeOrDateTime.new(DateTime.new(1969,12,31,23,59,59))))
|
335
435
|
end
|
336
436
|
|
337
|
-
assert(dti.period_for_utc(DateTime.new(2001,9,9,2,46,40)).
|
437
|
+
assert(dti.period_for_utc(DateTime.new(2001,9,9,2,46,40)).start_transition.at.eql?(TimeOrDateTime.new(1000000000)))
|
338
438
|
|
339
439
|
if RubyCoreSupport.time_supports_64bit
|
340
|
-
assert(dti.period_for_utc(DateTime.new(2038,1,19,3,14,8)).
|
440
|
+
assert(dti.period_for_utc(DateTime.new(2038,1,19,3,14,8)).start_transition.at.eql?(TimeOrDateTime.new(2147483648)))
|
341
441
|
else
|
342
|
-
assert(dti.period_for_utc(DateTime.new(2038,1,19,3,14,8)).
|
442
|
+
assert(dti.period_for_utc(DateTime.new(2038,1,19,3,14,8)).start_transition.at.eql?(TimeOrDateTime.new(DateTime.new(2038,1,19,3,14,8))))
|
343
443
|
end
|
344
444
|
end
|
345
445
|
end
|
@@ -216,6 +216,32 @@ class TCZoneinfoDataSource < Test::Unit::TestCase
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
+
def test_load_timezone_info_ignored_file
|
220
|
+
assert_raises(InvalidTimezoneIdentifier) do
|
221
|
+
@data_source.load_timezone_info('localtime')
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_load_timezone_info_ignored_plus_version_file
|
226
|
+
# Mac OS X includes a file named +VERSION containing the tzdata version.
|
227
|
+
|
228
|
+
Dir.mktmpdir('tzinfo_test') do |dir|
|
229
|
+
FileUtils.touch(File.join(dir, 'zone.tab'))
|
230
|
+
FileUtils.touch(File.join(dir, 'iso3166.tab'))
|
231
|
+
|
232
|
+
File.open(File.join(dir, '+VERSION'), 'w') do |f|
|
233
|
+
f.binmode
|
234
|
+
f.write("2013a\n")
|
235
|
+
end
|
236
|
+
|
237
|
+
data_source = ZoneinfoDataSource.new(dir)
|
238
|
+
|
239
|
+
assert_raises(InvalidTimezoneIdentifier) do
|
240
|
+
data_source.load_timezone_info('+VERSION')
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
219
245
|
def test_load_timezone_info_nil
|
220
246
|
assert_raises(InvalidTimezoneIdentifier) do
|
221
247
|
@data_source.load_timezone_info(nil)
|
@@ -416,9 +442,9 @@ class TCZoneinfoDataSource < Test::Unit::TestCase
|
|
416
442
|
zone = File.join(dir, 'Zone')
|
417
443
|
|
418
444
|
File.open(File.join(@data_source.zoneinfo_dir, 'EST')) do |src|
|
419
|
-
# Change
|
445
|
+
# Change header to TZif1 (which is not a valid header).
|
420
446
|
File.open(zone, 'wb') do |dest|
|
421
|
-
dest.write('
|
447
|
+
dest.write('TZif1')
|
422
448
|
src.pos = 5
|
423
449
|
FileUtils.copy_stream(src, dest)
|
424
450
|
end
|
@@ -434,13 +460,23 @@ class TCZoneinfoDataSource < Test::Unit::TestCase
|
|
434
460
|
|
435
461
|
def test_load_timezone_info_tainted
|
436
462
|
safe_test do
|
437
|
-
|
463
|
+
identifier = 'Europe/Amsterdam'.taint
|
464
|
+
assert(identifier.tainted?)
|
465
|
+
info = @data_source.load_timezone_info(identifier)
|
438
466
|
assert_equal('Europe/Amsterdam', info.identifier)
|
467
|
+
assert(identifier.tainted?)
|
439
468
|
end
|
440
469
|
end
|
441
470
|
|
442
|
-
def
|
471
|
+
def test_load_timezone_info_tainted_and_frozen
|
443
472
|
safe_test do
|
473
|
+
info = @data_source.load_timezone_info('Europe/Amsterdam'.taint.freeze)
|
474
|
+
assert_equal('Europe/Amsterdam', info.identifier)
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
def test_load_timezone_info_tainted_zoneinfo_dir_safe_mode
|
479
|
+
safe_test(:unavailable => :skip) do
|
444
480
|
assert_raises(SecurityError) do
|
445
481
|
ZoneinfoDataSource.new(@data_source.zoneinfo_dir.dup.taint)
|
446
482
|
end
|
@@ -509,6 +545,24 @@ class TCZoneinfoDataSource < Test::Unit::TestCase
|
|
509
545
|
end
|
510
546
|
end
|
511
547
|
|
548
|
+
def test_timezone_identifiers_ignored_plus_version_file
|
549
|
+
# Mac OS X includes a file named +VERSION containing the tzdata version.
|
550
|
+
|
551
|
+
Dir.mktmpdir('tzinfo_test') do |dir|
|
552
|
+
FileUtils.touch(File.join(dir, 'zone.tab'))
|
553
|
+
FileUtils.touch(File.join(dir, 'iso3166.tab'))
|
554
|
+
FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
|
555
|
+
|
556
|
+
File.open(File.join(dir, '+VERSION'), 'w') do |f|
|
557
|
+
f.binmode
|
558
|
+
f.write("2013a\n")
|
559
|
+
end
|
560
|
+
|
561
|
+
data_source = ZoneinfoDataSource.new(dir)
|
562
|
+
assert_array_same_items(['EST'], data_source.timezone_identifiers)
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
512
566
|
def test_load_country_info
|
513
567
|
info = @data_source.load_country_info('GB')
|
514
568
|
assert_equal('GB', info.code)
|
@@ -540,7 +594,17 @@ class TCZoneinfoDataSource < Test::Unit::TestCase
|
|
540
594
|
|
541
595
|
def test_load_country_info_tainted
|
542
596
|
safe_test do
|
543
|
-
|
597
|
+
code = 'NL'.taint
|
598
|
+
assert(code.tainted?)
|
599
|
+
info = @data_source.load_country_info(code)
|
600
|
+
assert_equal('NL', info.code)
|
601
|
+
assert(code.tainted?)
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
def test_load_country_info_tainted_and_frozen
|
606
|
+
safe_test do
|
607
|
+
info = @data_source.load_country_info('NL'.taint.freeze)
|
544
608
|
assert_equal('NL', info.code)
|
545
609
|
end
|
546
610
|
end
|
@@ -31,6 +31,14 @@ include TZInfo
|
|
31
31
|
|
32
32
|
class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
33
33
|
|
34
|
+
begin
|
35
|
+
Time.at(-2147483649)
|
36
|
+
Time.at(2147483648)
|
37
|
+
SUPPORTS_64BIT = true
|
38
|
+
rescue RangeError
|
39
|
+
SUPPORTS_64BIT = false
|
40
|
+
end
|
41
|
+
|
34
42
|
def assert_period(abbreviation, utc_offset, std_offset, dst, start_at, end_at, info)
|
35
43
|
if start_at
|
36
44
|
period = info.period_for_utc(start_at)
|
@@ -89,19 +97,26 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
89
97
|
|
90
98
|
# Options for testing malformed zoneinfo files.
|
91
99
|
magic = options[:magic]
|
100
|
+
section2_magic = options[:section2_magic]
|
92
101
|
abbrev_separator = options[:abbrev_separator] || "\0"
|
93
102
|
abbrev_offset_base = options[:abbrev_offset_base] || 0
|
94
103
|
|
95
104
|
unless magic
|
96
105
|
if format == 1
|
97
106
|
magic = "TZif\0"
|
98
|
-
elsif format
|
99
|
-
magic =
|
107
|
+
elsif format >= 2
|
108
|
+
magic = "TZif#{format}"
|
100
109
|
else
|
101
110
|
raise ArgumentError, 'Invalid format specified'
|
102
111
|
end
|
103
112
|
end
|
104
113
|
|
114
|
+
if section2_magic.kind_of?(Proc)
|
115
|
+
section2_magic = section2_magic.call(format)
|
116
|
+
else
|
117
|
+
section2_magic = magic unless section2_magic
|
118
|
+
end
|
119
|
+
|
105
120
|
convert_times_to_i(transitions)
|
106
121
|
convert_times_to_i(leaps)
|
107
122
|
|
@@ -155,9 +170,9 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
155
170
|
file.write("\0" * offsets.length * 2)
|
156
171
|
end
|
157
172
|
|
158
|
-
if format
|
173
|
+
if format >= 2
|
159
174
|
file.write(
|
160
|
-
[
|
175
|
+
[section2_magic, offsets.length, offsets.length, leaps.length,
|
161
176
|
transitions.length, offsets.length, abbrevs_length].pack('a5 x15 NNNNNN'))
|
162
177
|
|
163
178
|
unless transitions.empty?
|
@@ -198,8 +213,11 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
198
213
|
end
|
199
214
|
|
200
215
|
def tzif_test(offsets, transitions, leaps = [], options = {}, &block)
|
201
|
-
|
202
|
-
|
216
|
+
min_format = options[:min_format] || 1
|
217
|
+
|
218
|
+
min_format.upto(3) do |format|
|
219
|
+
write_tzif(format, offsets, transitions, leaps, options, &block)
|
220
|
+
end
|
203
221
|
end
|
204
222
|
|
205
223
|
def test_load
|
@@ -307,7 +325,7 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
307
325
|
end
|
308
326
|
|
309
327
|
def test_load_invalid_magic
|
310
|
-
['
|
328
|
+
['TZif4', 'tzif2', '12345'].each do |magic|
|
311
329
|
offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
|
312
330
|
|
313
331
|
tzif_test(offsets, [], [], :magic => magic) do |path, format|
|
@@ -318,6 +336,38 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
318
336
|
end
|
319
337
|
end
|
320
338
|
|
339
|
+
# These tests can only be run if the platform supports 64-bit Times. When
|
340
|
+
# 64-bit support is unavailable, the second section will not be read, so no
|
341
|
+
# error will be raised.
|
342
|
+
if SUPPORTS_64BIT
|
343
|
+
def test_load_invalid_section2_magic
|
344
|
+
['TZif4', 'tzif2', '12345'].each do |section2_magic|
|
345
|
+
offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
|
346
|
+
|
347
|
+
tzif_test(offsets, [], [], :min_format => 2, :section2_magic => section2_magic) do |path, format|
|
348
|
+
assert_raises(InvalidZoneinfoFile) do
|
349
|
+
ZoneinfoTimezoneInfo.new('Zone4', path)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_load_mismatched_section2_magic
|
356
|
+
minus_one = Proc.new {|f| f == 2 ? "TZif\0" : "TZif#{f - 1}" }
|
357
|
+
plus_one = Proc.new {|f| "TZif#{f + 1}" }
|
358
|
+
|
359
|
+
[minus_one, plus_one].each do |section2_magic|
|
360
|
+
offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
|
361
|
+
|
362
|
+
tzif_test(offsets, [], [], :min_format => 2, :section2_magic => section2_magic) do |path, format|
|
363
|
+
assert_raises(InvalidZoneinfoFile) do
|
364
|
+
ZoneinfoTimezoneInfo.new('Zone5', path)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
321
371
|
def test_load_invalid_format
|
322
372
|
Tempfile.open('tzinfo-test-zone') do |file|
|
323
373
|
file.write('Invalid')
|
@@ -399,21 +449,14 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
399
449
|
assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
|
400
450
|
end
|
401
451
|
end
|
402
|
-
|
452
|
+
|
403
453
|
def test_load_64bit
|
404
454
|
# Some platforms support 64-bit Times, others only 32-bit. The TZif version
|
405
|
-
# 2 format contains both 32-bit and 64-bit times.
|
455
|
+
# 2 and later format contains both 32-bit and 64-bit times.
|
406
456
|
|
407
|
-
# Where 64-bit is supported and a TZif 2 file is provided, the
|
408
|
-
# should be used, otherwise the 32-bit information should be
|
409
|
-
|
410
|
-
begin
|
411
|
-
Time.at(-2147483649)
|
412
|
-
Time.at(2147483648)
|
413
|
-
supports_64bit = true
|
414
|
-
rescue RangeError
|
415
|
-
supports_64bit = false
|
416
|
-
end
|
457
|
+
# Where 64-bit is supported and a TZif 2 or later file is provided, the
|
458
|
+
# 64-bit times should be used, otherwise the 32-bit information should be
|
459
|
+
# used.
|
417
460
|
|
418
461
|
offsets = [
|
419
462
|
{:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
|
@@ -431,7 +474,7 @@ class TCZoneinfoTimezoneInfo < Test::Unit::TestCase
|
|
431
474
|
info = ZoneinfoTimezoneInfo.new('Zone/SixtyFour', path)
|
432
475
|
assert_equal('Zone/SixtyFour', info.identifier)
|
433
476
|
|
434
|
-
if
|
477
|
+
if SUPPORTS_64BIT && format >= 2
|
435
478
|
assert_period(:LMT, 3542, 0, false, nil, Time.utc(1850, 1, 2), info)
|
436
479
|
assert_period(:XST, 3600, 0, false, Time.utc(1850, 1, 2), Time.utc(2003, 4, 22), info)
|
437
480
|
assert_period(:XDT, 3600, 3600, true, Time.utc(2003, 4, 22), Time.utc(2003, 10, 21), info)
|