tzinfo 1.2.6 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -1
  4. data/.yardopts +3 -0
  5. data/CHANGES.md +494 -380
  6. data/LICENSE +13 -13
  7. data/README.md +368 -114
  8. data/lib/tzinfo.rb +59 -29
  9. data/lib/tzinfo/country.rb +141 -129
  10. data/lib/tzinfo/country_timezone.rb +70 -112
  11. data/lib/tzinfo/data_source.rb +389 -144
  12. data/lib/tzinfo/data_sources.rb +8 -0
  13. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  14. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  15. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  16. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  17. data/lib/tzinfo/data_sources/ruby_data_source.rb +145 -0
  18. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  19. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  20. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +577 -0
  21. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +288 -0
  22. data/lib/tzinfo/data_timezone.rb +33 -47
  23. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  24. data/lib/tzinfo/format1.rb +10 -0
  25. data/lib/tzinfo/format1/country_definer.rb +17 -0
  26. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  27. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  28. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  29. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  30. data/lib/tzinfo/format2.rb +10 -0
  31. data/lib/tzinfo/format2/country_definer.rb +68 -0
  32. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  33. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  34. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  35. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  36. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  37. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  38. data/lib/tzinfo/info_timezone.rb +26 -21
  39. data/lib/tzinfo/linked_timezone.rb +33 -52
  40. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  41. data/lib/tzinfo/string_deduper.rb +118 -0
  42. data/lib/tzinfo/time_with_offset.rb +128 -0
  43. data/lib/tzinfo/timestamp.rb +548 -0
  44. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  45. data/lib/tzinfo/timezone.rb +989 -502
  46. data/lib/tzinfo/timezone_offset.rb +84 -74
  47. data/lib/tzinfo/timezone_period.rb +151 -217
  48. data/lib/tzinfo/timezone_proxy.rb +70 -79
  49. data/lib/tzinfo/timezone_transition.rb +77 -109
  50. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  51. data/lib/tzinfo/untaint_ext.rb +18 -0
  52. data/lib/tzinfo/version.rb +7 -0
  53. data/lib/tzinfo/with_offset.rb +61 -0
  54. metadata +44 -100
  55. metadata.gz.sig +0 -0
  56. data/Rakefile +0 -107
  57. data/lib/tzinfo/country_index_definition.rb +0 -31
  58. data/lib/tzinfo/country_info.rb +0 -42
  59. data/lib/tzinfo/data_timezone_info.rb +0 -55
  60. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  61. data/lib/tzinfo/offset_rationals.rb +0 -77
  62. data/lib/tzinfo/ruby_core_support.rb +0 -176
  63. data/lib/tzinfo/ruby_country_info.rb +0 -74
  64. data/lib/tzinfo/ruby_data_source.rb +0 -138
  65. data/lib/tzinfo/time_or_datetime.rb +0 -340
  66. data/lib/tzinfo/timezone_definition.rb +0 -36
  67. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  68. data/lib/tzinfo/timezone_info.rb +0 -30
  69. data/lib/tzinfo/timezone_transition_definition.rb +0 -104
  70. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  71. data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
  72. data/lib/tzinfo/zoneinfo_data_source.rb +0 -496
  73. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -298
  74. data/test/tc_country.rb +0 -236
  75. data/test/tc_country_index_definition.rb +0 -69
  76. data/test/tc_country_info.rb +0 -16
  77. data/test/tc_country_timezone.rb +0 -173
  78. data/test/tc_data_source.rb +0 -218
  79. data/test/tc_data_timezone.rb +0 -99
  80. data/test/tc_data_timezone_info.rb +0 -18
  81. data/test/tc_info_timezone.rb +0 -34
  82. data/test/tc_linked_timezone.rb +0 -155
  83. data/test/tc_linked_timezone_info.rb +0 -23
  84. data/test/tc_offset_rationals.rb +0 -23
  85. data/test/tc_ruby_core_support.rb +0 -168
  86. data/test/tc_ruby_country_info.rb +0 -110
  87. data/test/tc_ruby_data_source.rb +0 -165
  88. data/test/tc_time_or_datetime.rb +0 -660
  89. data/test/tc_timezone.rb +0 -1359
  90. data/test/tc_timezone_definition.rb +0 -113
  91. data/test/tc_timezone_index_definition.rb +0 -73
  92. data/test/tc_timezone_info.rb +0 -11
  93. data/test/tc_timezone_london.rb +0 -143
  94. data/test/tc_timezone_melbourne.rb +0 -142
  95. data/test/tc_timezone_new_york.rb +0 -142
  96. data/test/tc_timezone_offset.rb +0 -126
  97. data/test/tc_timezone_period.rb +0 -555
  98. data/test/tc_timezone_proxy.rb +0 -136
  99. data/test/tc_timezone_transition.rb +0 -366
  100. data/test/tc_timezone_transition_definition.rb +0 -295
  101. data/test/tc_timezone_utc.rb +0 -27
  102. data/test/tc_transition_data_timezone_info.rb +0 -433
  103. data/test/tc_zoneinfo_country_info.rb +0 -78
  104. data/test/tc_zoneinfo_data_source.rb +0 -1204
  105. data/test/tc_zoneinfo_timezone_info.rb +0 -1234
  106. data/test/test_utils.rb +0 -188
  107. data/test/ts_all.rb +0 -7
  108. data/test/ts_all_ruby.rb +0 -5
  109. data/test/ts_all_zoneinfo.rb +0 -9
  110. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  111. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  112. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -315
  113. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -218
  114. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  115. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  116. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  117. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  118. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -261
  119. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -186
  120. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -321
  121. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -265
  122. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -220
  123. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  124. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -927
  125. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -596
  126. data/test/tzinfo-data/tzinfo/data/version.rb +0 -14
  127. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  128. data/test/zoneinfo/America/New_York +0 -0
  129. data/test/zoneinfo/Australia/Melbourne +0 -0
  130. data/test/zoneinfo/EST +0 -0
  131. data/test/zoneinfo/Etc/UTC +0 -0
  132. data/test/zoneinfo/Europe/Amsterdam +0 -0
  133. data/test/zoneinfo/Europe/Andorra +0 -0
  134. data/test/zoneinfo/Europe/London +0 -0
  135. data/test/zoneinfo/Europe/Paris +0 -0
  136. data/test/zoneinfo/Europe/Prague +0 -0
  137. data/test/zoneinfo/Factory +0 -0
  138. data/test/zoneinfo/iso3166.tab +0 -275
  139. data/test/zoneinfo/leapseconds +0 -61
  140. data/test/zoneinfo/posix/Europe/London +0 -0
  141. data/test/zoneinfo/posixrules +0 -0
  142. data/test/zoneinfo/right/Europe/London +0 -0
  143. data/test/zoneinfo/zone.tab +0 -439
  144. data/test/zoneinfo/zone1970.tab +0 -369
  145. data/tzinfo.gemspec +0 -21
@@ -1,1234 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
4
- require 'tempfile'
5
-
6
- include TZInfo
7
-
8
- using RubyCoreSupport::UntaintExt if RubyCoreSupport.const_defined?(:UntaintExt)
9
-
10
- class TCZoneinfoTimezoneInfo < Minitest::Test
11
-
12
- begin
13
- Time.at(-2147483649)
14
- Time.at(2147483648)
15
- SUPPORTS_64BIT = true
16
- rescue RangeError
17
- SUPPORTS_64BIT = false
18
- end
19
-
20
- begin
21
- Time.at(-1)
22
- Time.at(-2147483648)
23
- SUPPORTS_NEGATIVE = true
24
- rescue ArgumentError
25
- SUPPORTS_NEGATIVE = false
26
- end
27
-
28
- def assert_period(abbreviation, utc_offset, std_offset, dst, start_at, end_at, info)
29
- if start_at
30
- period = info.period_for_utc(start_at)
31
- elsif end_at
32
- period = info.period_for_utc(TimeOrDateTime.wrap(end_at).add_with_convert(-1).to_orig)
33
- else
34
- # no transitions, pick the epoch
35
- period = info.period_for_utc(Time.utc(1970, 1, 1))
36
- end
37
-
38
- assert_equal(abbreviation, period.abbreviation)
39
- assert_equal(utc_offset, period.utc_offset)
40
- assert_equal(std_offset, period.std_offset)
41
- assert_equal(dst, period.dst?)
42
-
43
- if start_at
44
- refute_nil(period.utc_start_time)
45
- assert_equal(start_at, period.utc_start_time)
46
- else
47
- assert_nil(period.utc_start_time)
48
- end
49
-
50
- if end_at
51
- refute_nil(period.utc_end_time)
52
- assert_equal(end_at, period.utc_end_time)
53
- else
54
- assert_nil(period.utc_end_time)
55
- end
56
- end
57
-
58
- def convert_times_to_i(items, key = :at)
59
- items.each do |item|
60
- if item[key].kind_of?(Time)
61
- item[key] = item[key].utc.to_i
62
- end
63
- end
64
- end
65
-
66
- def select_with_32bit_values(items, key = :at)
67
- items.select do |item|
68
- i = item[key]
69
- i >= -2147483648 && i <= 2147483647
70
- end
71
- end
72
-
73
- def pack_int64_network_order(values)
74
- values.collect {|value| [value >> 32, value & 0xFFFFFFFF]}.flatten.pack('NN' * values.length)
75
- end
76
-
77
- def pack_int64_signed_network_order(values)
78
- # Convert to the equivalent 64-bit unsigned integer with the same bit representation
79
- pack_int64_network_order(values.collect {|value| value < 0 ? value + 0x10000000000000000 : value})
80
- end
81
-
82
- def write_tzif(format, offsets, transitions, leaps = [], options = {})
83
-
84
- # Options for testing malformed zoneinfo files.
85
- magic = options[:magic]
86
- section2_magic = options[:section2_magic]
87
- abbrev_separator = options[:abbrev_separator] || "\0"
88
- abbrev_offset_base = options[:abbrev_offset_base] || 0
89
-
90
- unless magic
91
- if format == 1
92
- magic = "TZif\0"
93
- elsif format >= 2
94
- magic = "TZif#{format}"
95
- else
96
- raise ArgumentError, 'Invalid format specified'
97
- end
98
- end
99
-
100
- if section2_magic.kind_of?(Proc)
101
- section2_magic = section2_magic.call(format)
102
- else
103
- section2_magic = magic unless section2_magic
104
- end
105
-
106
- convert_times_to_i(transitions)
107
- convert_times_to_i(leaps)
108
-
109
- abbrevs = offsets.collect {|o| o[:abbrev]}.uniq
110
-
111
- if abbrevs.length > 0
112
- abbrevs = abbrevs.collect {|a| a.encode('UTF-8')} if abbrevs.first.respond_to?(:encode)
113
-
114
- if abbrevs.first.respond_to?(:bytesize)
115
- abbrevs_length = abbrevs.inject(0) {|sum, a| sum + a.bytesize + abbrev_separator.bytesize}
116
- else
117
- abbrevs_length = abbrevs.inject(0) {|sum, a| sum + a.length + abbrev_separator.length}
118
- end
119
- else
120
- abbrevs_length = 0
121
- end
122
-
123
- b32_transitions = select_with_32bit_values(transitions)
124
- b32_leaps = select_with_32bit_values(leaps)
125
-
126
- Tempfile.open('tzinfo-test-zone') do |file|
127
- file.binmode
128
-
129
- file.write(
130
- [magic, offsets.length, offsets.length, leaps.length,
131
- b32_transitions.length, offsets.length, abbrevs_length].pack('a5 x15 NNNNNN'))
132
-
133
- unless b32_transitions.empty?
134
- file.write(b32_transitions.collect {|t| t[:at]}.pack('N' * b32_transitions.length))
135
- file.write(b32_transitions.collect {|t| t[:offset_index]}.pack('C' * b32_transitions.length))
136
- end
137
-
138
- offsets.each do |offset|
139
- index = abbrevs.index(offset[:abbrev])
140
- abbrev_offset = abbrev_offset_base
141
- 0.upto(index - 1) {|i| abbrev_offset += abbrevs[i].length + 1}
142
-
143
- file.write([offset[:gmtoff], offset[:isdst] ? 1 : 0, abbrev_offset].pack('NCC'))
144
- end
145
-
146
- abbrevs.each do |a|
147
- file.write(a)
148
- file.write(abbrev_separator)
149
- end
150
-
151
- b32_leaps.each do |leap|
152
- file.write([leap[:at], leap[:seconds]].pack('NN'))
153
- end
154
-
155
- unless offsets.empty?
156
- file.write("\0" * offsets.length * 2)
157
- end
158
-
159
- if format >= 2
160
- file.write(
161
- [section2_magic, offsets.length, offsets.length, leaps.length,
162
- transitions.length, offsets.length, abbrevs_length].pack('a5 x15 NNNNNN'))
163
-
164
- unless transitions.empty?
165
- file.write(pack_int64_signed_network_order(transitions.collect {|t| t[:at]}))
166
- file.write(transitions.collect {|t| t[:offset_index]}.pack('C' * transitions.length))
167
- end
168
-
169
- offsets.each do |offset|
170
- index = abbrevs.index(offset[:abbrev])
171
- abbrev_offset = abbrev_offset_base
172
- 0.upto(index - 1) {|i| abbrev_offset += abbrevs[i].length + 1}
173
-
174
- file.write([offset[:gmtoff], offset[:isdst] ? 1 : 0, abbrev_offset].pack('NCC'))
175
- end
176
-
177
- abbrevs.each do |a|
178
- file.write(a)
179
- file.write(abbrev_separator)
180
- end
181
-
182
- leaps.each do |leap|
183
- file.write(pack_int64_signed_network_order([leap[:at]]))
184
- file.write([leap[:seconds]].pack('N'))
185
- end
186
-
187
- unless offsets.empty?
188
- file.write("\0" * offsets.length * 2)
189
- end
190
-
191
- # Empty POSIX timezone string
192
- file.write("\n\n")
193
- end
194
-
195
- file.flush
196
-
197
- yield file.path, format
198
- end
199
- end
200
-
201
- def tzif_test(offsets, transitions, leaps = [], options = {}, &block)
202
- min_format = options[:min_format] || 1
203
-
204
- min_format.upto(3) do |format|
205
- write_tzif(format, offsets, transitions, leaps, options, &block)
206
- end
207
- end
208
-
209
- def test_load
210
- offsets = [
211
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
212
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
213
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
214
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
215
-
216
- transitions = [
217
- {:at => Time.utc(1971, 1, 2), :offset_index => 1},
218
- {:at => Time.utc(1980, 4, 22), :offset_index => 2},
219
- {:at => Time.utc(1980, 10, 21), :offset_index => 1},
220
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
221
-
222
- tzif_test(offsets, transitions) do |path, format|
223
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
224
- assert_equal('Zone/One', info.identifier)
225
-
226
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1971, 1, 2), info)
227
- assert_period(:XST, 3600, 0, false, Time.utc(1971, 1, 2), Time.utc(1980, 4, 22), info)
228
- assert_period(:XDT, 3600, 3600, true, Time.utc(1980, 4, 22), Time.utc(1980, 10, 21), info)
229
- assert_period(:XST, 3600, 0, false, Time.utc(1980, 10, 21), Time.utc(2000, 12, 31), info)
230
- assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
231
- end
232
- end
233
-
234
- def test_load_negative_utc_offset
235
- offsets = [
236
- {:gmtoff => -12492, :isdst => false, :abbrev => 'LMT'},
237
- {:gmtoff => -12000, :isdst => false, :abbrev => 'XST'},
238
- {:gmtoff => -8400, :isdst => true, :abbrev => 'XDT'},
239
- {:gmtoff => -8400, :isdst => false, :abbrev => 'XNST'}]
240
-
241
- transitions = [
242
- {:at => Time.utc(1971, 7, 9, 3, 0, 0), :offset_index => 1},
243
- {:at => Time.utc(1972, 10, 12, 3, 0, 0), :offset_index => 2},
244
- {:at => Time.utc(1973, 4, 29, 3, 0, 0), :offset_index => 1},
245
- {:at => Time.utc(1992, 4, 1, 4, 30, 0), :offset_index => 3}]
246
-
247
- tzif_test(offsets, transitions) do |path, format|
248
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
249
- assert_equal('Zone/One', info.identifier)
250
-
251
- assert_period(:LMT, -12492, 0, false, nil, Time.utc(1971, 7, 9, 3, 0, 0), info)
252
- assert_period(:XST, -12000, 0, false, Time.utc(1971, 7, 9, 3, 0, 0), Time.utc(1972, 10, 12, 3, 0, 0), info)
253
- assert_period(:XDT, -12000, 3600, true, Time.utc(1972, 10, 12, 3, 0, 0), Time.utc(1973, 4, 29, 3, 0, 0), info)
254
- assert_period(:XST, -12000, 0, false, Time.utc(1973, 4, 29, 3, 0, 0), Time.utc(1992, 4, 1, 4, 30, 0), info)
255
- assert_period(:XNST, -8400, 0, false, Time.utc(1992, 4, 1, 4, 30, 0), nil, info)
256
- end
257
- end
258
-
259
- def test_load_dst_first
260
- offsets = [
261
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
262
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
263
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
264
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
265
-
266
- transitions = [
267
- {:at => Time.utc(1979, 1, 2), :offset_index => 2},
268
- {:at => Time.utc(1980, 4, 22), :offset_index => 0},
269
- {:at => Time.utc(1980, 10, 21), :offset_index => 2},
270
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
271
-
272
- tzif_test(offsets, transitions) do |path, format|
273
- info = ZoneinfoTimezoneInfo.new('Zone/Two', path)
274
- assert_equal('Zone/Two', info.identifier)
275
-
276
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1979, 1, 2), info)
277
- end
278
- end
279
-
280
- def test_load_no_transitions
281
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
282
-
283
- tzif_test(offsets, []) do |path, format|
284
- info = ZoneinfoTimezoneInfo.new('Zone/three', path)
285
- assert_equal('Zone/three', info.identifier)
286
-
287
- assert_period(:LT, -12094, 0, false, nil, nil, info)
288
- end
289
- end
290
-
291
- def test_load_no_offsets
292
- offsets = []
293
- transitions = [{:at => Time.utc(2000, 12, 31), :offset_index => 0}]
294
-
295
- tzif_test(offsets, transitions) do |path, format|
296
- assert_raises(InvalidZoneinfoFile) do
297
- ZoneinfoTimezoneInfo.new('Zone', path)
298
- end
299
- end
300
- end
301
-
302
- def test_load_invalid_offset_index
303
- offsets = [{:gmtoff => -0, :isdst => false, :abbrev => 'LMT'}]
304
- transitions = [{:at => Time.utc(2000, 12, 31), :offset_index => 2}]
305
-
306
- tzif_test(offsets, transitions) do |path, format|
307
- assert_raises(InvalidZoneinfoFile) do
308
- ZoneinfoTimezoneInfo.new('Zone', path)
309
- end
310
- end
311
- end
312
-
313
- def test_load_with_leap_seconds
314
- offsets = [{:gmtoff => -0, :isdst => false, :abbrev => 'LMT'}]
315
- leaps = [{:at => Time.utc(1972,6,30,23,59,60), :seconds => 1}]
316
-
317
- tzif_test(offsets, [], leaps) do |path, format|
318
- assert_raises(InvalidZoneinfoFile) do
319
- ZoneinfoTimezoneInfo.new('Zone', path)
320
- end
321
- end
322
- end
323
-
324
- def test_load_invalid_magic
325
- ['TZif4', 'tzif2', '12345'].each do |magic|
326
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
327
-
328
- tzif_test(offsets, [], [], :magic => magic) do |path, format|
329
- assert_raises(InvalidZoneinfoFile) do
330
- ZoneinfoTimezoneInfo.new('Zone2', path)
331
- end
332
- end
333
- end
334
- end
335
-
336
- # These tests can only be run if the platform supports 64-bit Times. When
337
- # 64-bit support is unavailable, the second section will not be read, so no
338
- # error will be raised.
339
- if SUPPORTS_64BIT
340
- def test_load_invalid_section2_magic
341
- ['TZif4', 'tzif2', '12345'].each do |section2_magic|
342
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
343
-
344
- tzif_test(offsets, [], [], :min_format => 2, :section2_magic => section2_magic) do |path, format|
345
- assert_raises(InvalidZoneinfoFile) do
346
- ZoneinfoTimezoneInfo.new('Zone4', path)
347
- end
348
- end
349
- end
350
- end
351
-
352
- def test_load_mismatched_section2_magic
353
- minus_one = Proc.new {|f| f == 2 ? "TZif\0" : "TZif#{f - 1}" }
354
- plus_one = Proc.new {|f| "TZif#{f + 1}" }
355
-
356
- [minus_one, plus_one].each do |section2_magic|
357
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
358
-
359
- tzif_test(offsets, [], [], :min_format => 2, :section2_magic => section2_magic) do |path, format|
360
- assert_raises(InvalidZoneinfoFile) do
361
- ZoneinfoTimezoneInfo.new('Zone5', path)
362
- end
363
- end
364
- end
365
- end
366
- end
367
-
368
- def test_load_invalid_format
369
- Tempfile.open('tzinfo-test-zone') do |file|
370
- file.write('Invalid')
371
- file.flush
372
-
373
- assert_raises(InvalidZoneinfoFile) do
374
- ZoneinfoTimezoneInfo.new('Zone3', file.path)
375
- end
376
- end
377
- end
378
-
379
- def test_load_missing_abbrev_null_termination
380
- offsets = [
381
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
382
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
383
-
384
- transitions = [
385
- {:at => Time.utc(2000, 1, 1), :offset_index => 1}]
386
-
387
- tzif_test(offsets, transitions, [], :abbrev_separator => '^') do |path, format|
388
- assert_raises(InvalidZoneinfoFile) do
389
- ZoneinfoTimezoneInfo.new('Zone', path)
390
- end
391
- end
392
- end
393
-
394
- def test_load_out_of_range_abbrev_offsets
395
- offsets = [
396
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
397
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
398
-
399
- transitions = [
400
- {:at => Time.utc(2000, 1, 1), :offset_index => 1}]
401
-
402
- tzif_test(offsets, transitions, [], :abbrev_offset_base => 8) do |path, format|
403
- assert_raises(InvalidZoneinfoFile) do
404
- ZoneinfoTimezoneInfo.new('Zone', path)
405
- end
406
- end
407
- end
408
-
409
- def test_load_before_epoch
410
- # Some platforms don't support negative timestamps for times before the
411
- # epoch. Check that they are returned when supported and skipped when not.
412
-
413
- # Note the last transition before the epoch (and within the 32-bit range) is
414
- # moved to the epoch on platforms that do not support negative timestamps.
415
-
416
- offsets = [
417
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
418
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
419
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
420
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
421
-
422
- transitions = [
423
- {:at => -694224000, :offset_index => 1}, # Time.utc(1948, 1, 2)
424
- {:at => -21945600, :offset_index => 2}, # Time.utc(1969, 4, 22)
425
- {:at => Time.utc(1970, 10, 21), :offset_index => 1},
426
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
427
-
428
- tzif_test(offsets, transitions) do |path, format|
429
- info = ZoneinfoTimezoneInfo.new('Zone/Negative', path)
430
- assert_equal('Zone/Negative', info.identifier)
431
-
432
- if SUPPORTS_NEGATIVE
433
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1948, 1, 2), info)
434
- assert_period(:XST, 3600, 0, false, Time.utc(1948, 1, 2), Time.utc(1969, 4, 22), info)
435
- assert_period(:XDT, 3600, 3600, true, Time.utc(1969, 4, 22), Time.utc(1970, 10, 21), info)
436
- else
437
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1970, 1, 1), info)
438
- assert_period(:XDT, 3600, 3600, true, Time.utc(1970, 1, 1), Time.utc(1970, 10, 21), info)
439
- end
440
-
441
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 10, 21), Time.utc(2000, 12, 31), info)
442
- assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
443
- end
444
- end
445
-
446
- def test_load_on_epoch
447
- offsets = [
448
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
449
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
450
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
451
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
452
-
453
- transitions = [
454
- {:at => -694224000, :offset_index => 1}, # Time.utc(1948, 1, 2)
455
- {:at => -21945600, :offset_index => 2}, # Time.utc(1969, 4, 22)
456
- {:at => Time.utc(1970, 1, 1), :offset_index => 1},
457
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
458
-
459
- tzif_test(offsets, transitions) do |path, format|
460
- info = ZoneinfoTimezoneInfo.new('Zone/Negative', path)
461
- assert_equal('Zone/Negative', info.identifier)
462
-
463
- if SUPPORTS_NEGATIVE
464
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1948, 1, 2), info)
465
- assert_period(:XST, 3600, 0, false, Time.utc(1948, 1, 2), Time.utc(1969, 4, 22), info)
466
- assert_period(:XDT, 3600, 3600, true, Time.utc(1969, 4, 22), Time.utc(1970, 1, 1), info)
467
- else
468
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1970, 1, 1), info)
469
- end
470
-
471
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 1, 1), Time.utc(2000, 12, 31), info)
472
- assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
473
- end
474
- end
475
-
476
- def test_load_64bit
477
- # Some platforms support 64-bit Times, others only 32-bit. The TZif version
478
- # 2 and later format contains both 32-bit and 64-bit times.
479
-
480
- # Where 64-bit is supported and a TZif 2 or later file is provided, the
481
- # 64-bit times should be used, otherwise the 32-bit information should be
482
- # used.
483
-
484
- offsets = [
485
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
486
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
487
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
488
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
489
-
490
- transitions = [
491
- {:at => -3786739200, :offset_index => 1}, # Time.utc(1850, 1, 2)
492
- {:at => Time.utc(2003, 4, 22), :offset_index => 2},
493
- {:at => Time.utc(2003, 10, 21), :offset_index => 1},
494
- {:at => 2240524800, :offset_index => 3}] # Time.utc(2040, 12, 31)
495
-
496
- tzif_test(offsets, transitions) do |path, format|
497
- info = ZoneinfoTimezoneInfo.new('Zone/SixtyFour', path)
498
- assert_equal('Zone/SixtyFour', info.identifier)
499
-
500
- if SUPPORTS_64BIT && format >= 2
501
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1850, 1, 2), info)
502
- assert_period(:XST, 3600, 0, false, Time.utc(1850, 1, 2), Time.utc(2003, 4, 22), info)
503
- assert_period(:XDT, 3600, 3600, true, Time.utc(2003, 4, 22), Time.utc(2003, 10, 21), info)
504
- assert_period(:XST, 3600, 0, false, Time.utc(2003, 10, 21), Time.utc(2040, 12, 31), info)
505
- assert_period(:XNST, 0, 0, false, Time.utc(2040, 12, 31), nil, info)
506
- else
507
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2003, 4, 22), info)
508
- assert_period(:XDT, 3600, 3600, true, Time.utc(2003, 4, 22), Time.utc(2003, 10, 21), info)
509
- assert_period(:XST, 3600, 0, false, Time.utc(2003, 10, 21), nil, info)
510
- end
511
- end
512
- end
513
-
514
- def test_load_64bit_range
515
- # The full range of 64 bit timestamps is not currently supported because of
516
- # the way transitions are indexed. Transitions outside the supported range
517
- # will be ignored.
518
-
519
- offsets = [
520
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
521
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
522
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
523
-
524
- transitions = [
525
- {:at => -2**63, :offset_index => 1},
526
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
527
- {:at => 2**63 - 1, :offset_index => 0}]
528
-
529
- tzif_test(offsets, transitions) do |path, format|
530
- info = ZoneinfoTimezoneInfo.new('Zone/SixtyFourRange', path)
531
- assert_equal('Zone/SixtyFourRange', info.identifier)
532
-
533
- if SUPPORTS_64BIT && format >= 2
534
- # When the full range is supported, the following periods will be defined:
535
- #assert_period(:LMT, 3542, 0, false, nil, Time.at(-2**63).utc, info)
536
- #assert_period(:XST, 3600, 0, false, Time.at(-2**63).utc, Time.utc(2014, 5, 27), info)
537
- #assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**63 - 1).utc, info)
538
- #assert_period(:LMT, 3542, 0, false, Time.at(2**63 - 1).utc, nil, info)
539
-
540
- # Without full range support, the following periods will be defined:
541
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
542
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
543
- else
544
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
545
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
546
- end
547
- end
548
- end
549
-
550
- def test_load_supported_64bit_range
551
- # The full range of 64 bit timestamps is not currently supported because of
552
- # the way transitions are indexed. Transitions outside the supported range
553
- # will be ignored.
554
-
555
- min_timestamp = -8520336000 # Time.utc(1700, 1, 1).to_i
556
- max_timestamp = 16725225600 # Time.utc(2500, 1, 1).to_i
557
-
558
- offsets = [
559
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
560
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
561
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
562
-
563
- transitions = [
564
- {:at => min_timestamp, :offset_index => 1},
565
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
566
- {:at => max_timestamp - 1, :offset_index => 0}]
567
-
568
- tzif_test(offsets, transitions) do |path, format|
569
- info = ZoneinfoTimezoneInfo.new('Zone/SupportedSixtyFourRange', path)
570
- assert_equal('Zone/SupportedSixtyFourRange', info.identifier)
571
-
572
- if SUPPORTS_64BIT && format >= 2
573
- assert_period(:LMT, 3542, 0, false, nil, Time.at(min_timestamp).utc, info)
574
- assert_period(:XST, 3600, 0, false, Time.at(min_timestamp).utc, Time.utc(2014, 5, 27), info)
575
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(max_timestamp - 1).utc, info)
576
- assert_period(:LMT, 3542, 0, false, Time.at(max_timestamp - 1).utc, nil, info)
577
- else
578
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
579
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
580
- end
581
- end
582
- end
583
-
584
- def test_load_32bit_range
585
- offsets = [
586
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
587
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
588
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
589
-
590
- transitions = [
591
- {:at => -2**31, :offset_index => 1},
592
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
593
- {:at => 2**31 - 1, :offset_index => 0}]
594
-
595
- tzif_test(offsets, transitions) do |path, format|
596
- info = ZoneinfoTimezoneInfo.new('Zone/ThirtyTwoRange', path)
597
- assert_equal('Zone/ThirtyTwoRange', info.identifier)
598
-
599
- if SUPPORTS_NEGATIVE
600
- assert_period(:LMT, 3542, 0, false, nil, Time.at(-2**31).utc, info)
601
- assert_period(:XST, 3600, 0, false, Time.at(-2**31).utc, Time.utc(2014, 5, 27), info)
602
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**31 - 1).utc, info)
603
- assert_period(:LMT, 3542, 0, false, Time.at(2**31 - 1).utc, nil, info)
604
- else
605
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 1, 1), Time.utc(2014, 5, 27), info)
606
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**31 - 1).utc, info)
607
- assert_period(:LMT, 3542, 0, false, Time.at(2**31 - 1).utc, nil, info)
608
- end
609
- end
610
- end
611
-
612
- def test_load_std_offset_changes
613
- # The zoneinfo files don't include the offset from standard time, so this
614
- # has to be derived by looking at changes in the total UTC offset.
615
-
616
- offsets = [
617
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
618
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
619
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
620
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
621
-
622
- transitions = [
623
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
624
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
625
- {:at => Time.utc(2000, 3, 1), :offset_index => 3},
626
- {:at => Time.utc(2000, 4, 1), :offset_index => 1}]
627
-
628
- tzif_test(offsets, transitions) do |path, format|
629
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
630
- assert_equal('Zone/DoubleDaylight', info.identifier)
631
-
632
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
633
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
634
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
635
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
636
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 4, 1), nil, info)
637
- end
638
- end
639
-
640
- def test_load_std_offset_changes_jump_to_double_dst
641
- # The zoneinfo files don't include the offset from standard time, so this
642
- # has to be derived by looking at changes in the total UTC offset.
643
-
644
- offsets = [
645
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
646
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
647
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
648
-
649
- transitions = [
650
- {:at => Time.utc(2000, 4, 1), :offset_index => 1},
651
- {:at => Time.utc(2000, 5, 1), :offset_index => 2},
652
- {:at => Time.utc(2000, 6, 1), :offset_index => 1}]
653
-
654
- tzif_test(offsets, transitions) do |path, format|
655
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
656
- assert_equal('Zone/DoubleDaylight', info.identifier)
657
-
658
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 4, 1), info)
659
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
660
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
661
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 6, 1), nil, info)
662
- end
663
- end
664
-
665
- def test_load_std_offset_changes_negative
666
- # The zoneinfo files don't include the offset from standard time, so this
667
- # has to be derived by looking at changes in the total UTC offset.
668
-
669
- offsets = [
670
- {:gmtoff => -10821, :isdst => false, :abbrev => 'LMT'},
671
- {:gmtoff => -10800, :isdst => false, :abbrev => 'XST'},
672
- {:gmtoff => -7200, :isdst => true, :abbrev => 'XDT'},
673
- {:gmtoff => -3600, :isdst => true, :abbrev => 'XDDT'}]
674
-
675
- transitions = [
676
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
677
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
678
- {:at => Time.utc(2000, 3, 1), :offset_index => 3},
679
- {:at => Time.utc(2000, 4, 1), :offset_index => 1},
680
- {:at => Time.utc(2000, 5, 1), :offset_index => 3},
681
- {:at => Time.utc(2000, 6, 1), :offset_index => 1}]
682
-
683
- tzif_test(offsets, transitions) do |path, format|
684
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
685
- assert_equal('Zone/DoubleDaylight', info.identifier)
686
-
687
- assert_period(:LMT, -10821, 0, false, nil, Time.utc(2000, 1, 1), info)
688
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
689
- assert_period(:XDT, -10800, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
690
- assert_period(:XDDT, -10800, 7200, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
691
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
692
- assert_period(:XDDT, -10800, 7200, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
693
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 6, 1), nil, info)
694
- end
695
- end
696
-
697
- def test_load_starts_two_hour_std_offset
698
- # The zoneinfo files don't include the offset from standard time, so this
699
- # has to be derived by looking at changes in the total UTC offset.
700
-
701
- offsets = [
702
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
703
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
704
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
705
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
706
-
707
- transitions = [
708
- {:at => Time.utc(2000, 1, 1), :offset_index => 3},
709
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
710
- {:at => Time.utc(2000, 3, 1), :offset_index => 1}]
711
-
712
- tzif_test(offsets, transitions) do |path, format|
713
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
714
- assert_equal('Zone/DoubleDaylight', info.identifier)
715
-
716
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
717
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
718
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
719
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
720
- end
721
- end
722
-
723
- def test_load_starts_only_dst_transition_with_lmt
724
- # The zoneinfo files don't include the offset from standard time, so this
725
- # has to be derived by looking at changes in the total UTC offset.
726
-
727
- offsets = [
728
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
729
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
730
-
731
- transitions = [{:at => Time.utc(2000, 1, 1), :offset_index => 1}]
732
-
733
- tzif_test(offsets, transitions) do |path, format|
734
- info = ZoneinfoTimezoneInfo.new('Zone/OnlyDST', path)
735
- assert_equal('Zone/OnlyDST', info.identifier)
736
-
737
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
738
- assert_period(:XDT, 3542, 3658, true, Time.utc(2000, 1, 1), nil, info)
739
- end
740
- end
741
-
742
- def test_load_starts_only_dst_transition_without_lmt
743
- # The zoneinfo files don't include the offset from standard time, so this
744
- # has to be derived by looking at changes in the total UTC offset.
745
-
746
- offsets = [{:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
747
-
748
- transitions = [{:at => Time.utc(2000, 1, 1), :offset_index => 0}]
749
-
750
- tzif_test(offsets, transitions) do |path, format|
751
- info = ZoneinfoTimezoneInfo.new('Zone/OnlyDST', path)
752
- assert_equal('Zone/OnlyDST', info.identifier)
753
-
754
- assert_period(:XDT, 3600, 3600, true, nil, Time.utc(2000, 1, 1), info)
755
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 1, 1), nil, info)
756
- end
757
- end
758
-
759
- def test_load_switch_to_dst_and_change_utc_offset
760
- # The zoneinfo files don't include the offset from standard time, so this
761
- # has to be derived by looking at changes in the total UTC offset.
762
-
763
- # Switch from non-DST to DST at the same time as moving the UTC offset
764
- # back an hour (i.e. wall clock time doesn't change).
765
-
766
- offsets = [
767
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
768
- {:gmtoff => 3600, :isdst => false, :abbrev => 'YST'},
769
- {:gmtoff => 3600, :isdst => true, :abbrev => 'XDT'}]
770
-
771
- transitions = [
772
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
773
- {:at => Time.utc(2000, 2, 1), :offset_index => 2}]
774
-
775
- tzif_test(offsets, transitions) do |path, format|
776
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
777
- assert_equal('Zone/DoubleDaylight', info.identifier)
778
-
779
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
780
- assert_period(:YST, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
781
- assert_period(:XDT, 0, 3600, true, Time.utc(2000, 2, 1), nil, info)
782
- end
783
- end
784
-
785
- def test_load_apia_international_dateline_change
786
- # The zoneinfo files don't include the offset from standard time, so this
787
- # has to be derived by looking at changes in the total UTC offset.
788
-
789
- # Pacific/Apia moved across the International Date Line whilst observing
790
- # daylight savings time.
791
-
792
- offsets = [
793
- {:gmtoff => 45184, :isdst => false, :abbrev => 'LMT'},
794
- {:gmtoff => -39600, :isdst => false, :abbrev => '-11'},
795
- {:gmtoff => -36000, :isdst => true, :abbrev => '-10'},
796
- {:gmtoff => 50400, :isdst => true, :abbrev => '+14'},
797
- {:gmtoff => 46800, :isdst => false, :abbrev => '+13'}]
798
-
799
- transitions = [
800
- {:at => Time.utc(2011, 4, 2, 14, 0, 0), :offset_index => 1},
801
- {:at => Time.utc(2011, 9, 24, 14, 0, 0), :offset_index => 2},
802
- {:at => Time.utc(2011, 12, 30, 10, 0, 0), :offset_index => 3},
803
- {:at => Time.utc(2012, 3, 31, 14, 0, 0), :offset_index => 4}]
804
-
805
- tzif_test(offsets, transitions) do |path, format|
806
- info = ZoneinfoTimezoneInfo.new('Test/Pacific/Apia', path)
807
- assert_equal('Test/Pacific/Apia', info.identifier)
808
-
809
- assert_period( :LMT, 45184, 0, false, nil, Time.utc(2011, 4, 2, 14, 0, 0), info)
810
- assert_period(:'-11', -39600, 0, false, Time.utc(2011, 4, 2, 14, 0, 0), Time.utc(2011, 9, 24, 14, 0, 0), info)
811
- assert_period(:'-10', -39600, 3600, true, Time.utc(2011, 9, 24, 14, 0, 0), Time.utc(2011, 12, 30, 10, 0, 0), info)
812
- assert_period(:'+14', 46800, 3600, true, Time.utc(2011, 12, 30, 10, 0, 0), Time.utc(2012, 3, 31, 14, 0, 0), info)
813
- assert_period(:'+13', 46800, 0, false, Time.utc(2012, 3, 31, 14, 0, 0), nil, info)
814
- end
815
- end
816
-
817
- def test_load_offset_split_for_different_utc_offset
818
- # The zoneinfo files don't include the offset from standard time, so this
819
- # has to be derived by looking at changes in the total UTC offset.
820
-
821
- offsets = [
822
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
823
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
824
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
825
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
826
-
827
- transitions = [
828
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
829
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
830
- {:at => Time.utc(2000, 3, 1), :offset_index => 1},
831
- {:at => Time.utc(2000, 4, 1), :offset_index => 2},
832
- {:at => Time.utc(2000, 5, 1), :offset_index => 3},
833
- {:at => Time.utc(2000, 6, 1), :offset_index => 2},
834
- {:at => Time.utc(2000, 7, 1), :offset_index => 1},
835
- {:at => Time.utc(2000, 8, 1), :offset_index => 3},
836
- {:at => Time.utc(2000, 9, 1), :offset_index => 1},
837
- {:at => Time.utc(2000, 10, 1), :offset_index => 2},
838
- {:at => Time.utc(2000, 11, 1), :offset_index => 3},
839
- {:at => Time.utc(2000, 12, 1), :offset_index => 2}]
840
-
841
- # XDT will be split and defined according to its surrounding standard time
842
- # offsets.
843
-
844
- tzif_test(offsets, transitions) do |path, format|
845
- info = ZoneinfoTimezoneInfo.new('Zone/SplitUtcOffset', path)
846
- assert_equal('Zone/SplitUtcOffset', info.identifier)
847
-
848
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
849
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
850
- assert_period( :XDT, 3600, 7200, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
851
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
852
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
853
- assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
854
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 6, 1), Time.utc(2000, 7, 1), info)
855
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 7, 1), Time.utc(2000, 8, 1), info)
856
- assert_period( :XDT, 3600, 7200, true, Time.utc(2000, 8, 1), Time.utc(2000, 9, 1), info)
857
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 9, 1), Time.utc(2000, 10, 1), info)
858
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 10, 1), Time.utc(2000, 11, 1), info)
859
- assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 11, 1), Time.utc(2000, 12, 1), info)
860
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 12, 1), nil, info)
861
-
862
- 1.upto(6) do |i|
863
- assert_same(info.period_for_utc(Time.utc(2000, i, 1)).offset, info.period_for_utc(Time.utc(2000, i + 6, 1)).offset)
864
- end
865
- end
866
- end
867
-
868
- def test_load_offset_utc_offset_taken_from_minimum_difference_minimum_after
869
- # The zoneinfo files don't include the offset from standard time, so this
870
- # has to be derived by looking at changes in the total UTC offset.
871
-
872
- offsets = [
873
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
874
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
875
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
876
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
877
-
878
- transitions = [
879
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
880
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
881
- {:at => Time.utc(2000, 3, 1), :offset_index => 2}]
882
-
883
- # XDT should use the closest utc_offset (7200) (and not an equivalent
884
- # utc_offset of 3600 and std_offset of 7200).
885
-
886
- tzif_test(offsets, transitions) do |path, format|
887
- info = ZoneinfoTimezoneInfo.new('Zone/MinimumUtcOffset', path)
888
- assert_equal('Zone/MinimumUtcOffset', info.identifier)
889
-
890
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
891
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
892
- assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
893
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
894
- end
895
- end
896
-
897
- def test_load_offset_utc_offset_taken_from_minimum_difference_minimum_before
898
- # The zoneinfo files don't include the offset from standard time, so this
899
- # has to be derived by looking at changes in the total UTC offset.
900
-
901
- offsets = [
902
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
903
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
904
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
905
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT'}]
906
-
907
- transitions = [
908
- {:at => Time.utc(2000, 1, 1), :offset_index => 2},
909
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
910
- {:at => Time.utc(2000, 3, 1), :offset_index => 1}]
911
-
912
- # XDT should use the closest utc_offset (7200) (and not an equivalent
913
- # utc_offset of 3600 and std_offset of 7200).
914
-
915
- tzif_test(offsets, transitions) do |path, format|
916
- info = ZoneinfoTimezoneInfo.new('Zone/MinimumUtcOffset', path)
917
- assert_equal('Zone/MinimumUtcOffset', info.identifier)
918
-
919
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
920
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
921
- assert_period( :XDT, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
922
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
923
- end
924
- end
925
-
926
- def test_load_offset_does_not_use_equal_utc_total_offset_equal_after
927
- # The zoneinfo files don't include the offset from standard time, so this
928
- # has to be derived by looking at changes in the total UTC offset.
929
-
930
- offsets = [
931
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
932
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
933
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
934
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
935
-
936
- transitions = [
937
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
938
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
939
- {:at => Time.utc(2000, 3, 1), :offset_index => 2}]
940
-
941
- # XDT will be based on the utc_offset of XST1 even though XST2 has an
942
- # equivalent (or greater) utc_total_offset.
943
-
944
- tzif_test(offsets, transitions) do |path, format|
945
- info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetEqual', path)
946
- assert_equal('Zone/UtcOffsetEqual', info.identifier)
947
-
948
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
949
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
950
- assert_period( :XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
951
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
952
- end
953
- end
954
-
955
- def test_load_offset_does_not_use_equal_utc_total_offset_equal_before
956
- # The zoneinfo files don't include the offset from standard time, so this
957
- # has to be derived by looking at changes in the total UTC offset.
958
-
959
- offsets = [
960
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
961
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
962
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
963
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
964
-
965
- transitions = [
966
- {:at => Time.utc(2000, 1, 1), :offset_index => 2},
967
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
968
- {:at => Time.utc(2000, 3, 1), :offset_index => 1}]
969
-
970
- # XDT will be based on the utc_offset of XST1 even though XST2 has an
971
- # equivalent (or greater) utc_total_offset.
972
-
973
- tzif_test(offsets, transitions) do |path, format|
974
- info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetEqual', path)
975
- assert_equal('Zone/UtcOffsetEqual', info.identifier)
976
-
977
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
978
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
979
- assert_period( :XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
980
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
981
- end
982
- end
983
-
984
- def test_load_offset_both_adjacent_non_dst_equal_utc_total_offset
985
- # The zoneinfo files don't include the offset from standard time, so this
986
- # has to be derived by looking at changes in the total UTC offset.
987
-
988
- offsets = [
989
- {:gmtoff => 7142, :isdst => false, :abbrev => 'LMT'},
990
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST'},
991
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'}]
992
-
993
- transitions = [
994
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
995
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
996
- {:at => Time.utc(2000, 3, 1), :offset_index => 1}]
997
-
998
- # XDT will just assume an std_offset of +1 hour and calculate the utc_offset
999
- # from utc_total_offset - std_offset.
1000
-
1001
- tzif_test(offsets, transitions) do |path, format|
1002
- info = ZoneinfoTimezoneInfo.new('Zone/AdjacentEqual', path)
1003
- assert_equal('Zone/AdjacentEqual', info.identifier)
1004
-
1005
- assert_period(:LMT, 7142, 0, false, nil, Time.utc(2000, 1, 1), info)
1006
- assert_period(:XST, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1007
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1008
- assert_period(:XST, 7200, 0, false, Time.utc(2000, 3, 1), nil, info)
1009
- end
1010
- end
1011
-
1012
- def test_load_offset_utc_offset_preserved_from_next
1013
- # The zoneinfo files don't include the offset from standard time, so this
1014
- # has to be derived by looking at changes in the total UTC offset.
1015
-
1016
- offsets = [
1017
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
1018
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
1019
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
1020
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT1'},
1021
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT2'}]
1022
-
1023
- transitions = [
1024
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
1025
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
1026
- {:at => Time.utc(2000, 3, 1), :offset_index => 4},
1027
- {:at => Time.utc(2000, 4, 1), :offset_index => 2}]
1028
-
1029
- # Both XDT1 and XDT2 should both use the closest utc_offset (7200) (and not
1030
- # an equivalent utc_offset of 3600 and std_offset of 7200).
1031
-
1032
- tzif_test(offsets, transitions) do |path, format|
1033
- info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetPreserved', path)
1034
- assert_equal('Zone/UtcOffsetPreserved', info.identifier)
1035
-
1036
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
1037
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1038
- assert_period(:XDT1, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1039
- assert_period(:XDT2, 7200, 3600, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
1040
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 4, 1), nil, info)
1041
- end
1042
- end
1043
-
1044
- def test_load_offset_utc_offset_preserved_from_previous
1045
- # The zoneinfo files don't include the offset from standard time, so this
1046
- # has to be derived by looking at changes in the total UTC offset.
1047
-
1048
- offsets = [
1049
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
1050
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST1'},
1051
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XST2'},
1052
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT1'},
1053
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDT2'}]
1054
-
1055
- transitions = [
1056
- {:at => Time.utc(2000, 1, 1), :offset_index => 2},
1057
- {:at => Time.utc(2000, 2, 1), :offset_index => 3},
1058
- {:at => Time.utc(2000, 3, 1), :offset_index => 4},
1059
- {:at => Time.utc(2000, 4, 1), :offset_index => 1}]
1060
-
1061
- # Both XDT1 and XDT2 should both use the closest utc_offset (7200) (and not
1062
- # an equivalent utc_offset of 3600 and std_offset of 7200).
1063
-
1064
- tzif_test(offsets, transitions) do |path, format|
1065
- info = ZoneinfoTimezoneInfo.new('Zone/UtcOffsetPreserved', path)
1066
- assert_equal('Zone/UtcOffsetPreserved', info.identifier)
1067
-
1068
- assert_period( :LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
1069
- assert_period(:XST2, 7200, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1070
- assert_period(:XDT1, 7200, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1071
- assert_period(:XDT2, 7200, 3600, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
1072
- assert_period(:XST1, 3600, 0, false, Time.utc(2000, 4, 1), nil, info)
1073
- end
1074
- end
1075
-
1076
- def test_read_offset_negative_std_offset_dst
1077
- # The zoneinfo files don't include the offset from standard time, so this
1078
- # has to be derived by looking at changes in the total UTC offset.
1079
-
1080
- offsets = [
1081
- {:gmtoff => -100, :isdst => false, :abbrev => 'LMT'},
1082
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
1083
- {:gmtoff => 0, :isdst => true, :abbrev => 'XWT'}]
1084
-
1085
- transitions = [
1086
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
1087
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
1088
- {:at => Time.utc(2000, 3, 1), :offset_index => 1},
1089
- {:at => Time.utc(2000, 4, 1), :offset_index => 2},
1090
- {:at => Time.utc(2000, 5, 1), :offset_index => 1}]
1091
-
1092
- tzif_test(offsets, transitions) do |path, format|
1093
- info = ZoneinfoTimezoneInfo.new('Zone/NegativeStdOffsetDst', path)
1094
- assert_equal('Zone/NegativeStdOffsetDst', info.identifier)
1095
-
1096
- assert_period(:LMT, -100, 0, false, nil, Time.utc(2000, 1, 1), info)
1097
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1098
- assert_period(:XWT, 3600, -3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1099
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
1100
- assert_period(:XWT, 3600, -3600, true, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
1101
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 5, 1), nil, info)
1102
- end
1103
- end
1104
-
1105
- def test_read_offset_negative_std_offset_dst_initial_dst
1106
- # The zoneinfo files don't include the offset from standard time, so this
1107
- # has to be derived by looking at changes in the total UTC offset.
1108
-
1109
- offsets = [
1110
- {:gmtoff => -100, :isdst => false, :abbrev => 'LMT'},
1111
- {:gmtoff => 0, :isdst => true, :abbrev => 'XWT'},
1112
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
1113
-
1114
- transitions = [
1115
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
1116
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
1117
- {:at => Time.utc(2000, 3, 1), :offset_index => 1},
1118
- {:at => Time.utc(2000, 4, 1), :offset_index => 2},
1119
- {:at => Time.utc(2000, 5, 1), :offset_index => 1}]
1120
-
1121
- tzif_test(offsets, transitions) do |path, format|
1122
- info = ZoneinfoTimezoneInfo.new('Zone/NegativeStdOffsetDstInitialDst', path)
1123
- assert_equal('Zone/NegativeStdOffsetDstInitialDst', info.identifier)
1124
-
1125
- assert_period(:LMT, -100, 0, false, nil, Time.utc(2000, 1, 1), info)
1126
- assert_period(:XWT, 3600, -3600, true, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1127
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1128
- assert_period(:XWT, 3600, -3600, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
1129
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
1130
- assert_period(:XWT, 3600, -3600, true, Time.utc(2000, 5, 1), nil, info)
1131
- end
1132
- end
1133
-
1134
- def test_read_offset_prefer_base_offset_moves_to_dst_not_hour
1135
- offsets = [
1136
- {:gmtoff => -100, :isdst => false, :abbrev => 'LMT'},
1137
- {:gmtoff => 0, :isdst => false, :abbrev => 'XST'},
1138
- {:gmtoff => 1800, :isdst => true, :abbrev => 'XDT'},
1139
- {:gmtoff => 1800, :isdst => false, :abbrev => 'XST'}]
1140
-
1141
- transitions = [
1142
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
1143
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
1144
- {:at => Time.utc(2000, 3, 1), :offset_index => 3}]
1145
-
1146
- tzif_test(offsets, transitions) do |path, format|
1147
- info = ZoneinfoTimezoneInfo.new('Zone/BaseOffsetMovesToDstNotHour', path)
1148
- assert_equal('Zone/BaseOffsetMovesToDstNotHour', info.identifier)
1149
-
1150
- assert_period(:LMT, -100, 0, false, nil, Time.utc(2000, 1, 1), info)
1151
- assert_period(:XST, 0, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1152
- assert_period(:XDT, 0, 1800, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1153
- assert_period(:XST, 1800, 0, false, Time.utc(2000, 3, 1), nil, info)
1154
- end
1155
- end
1156
-
1157
- def test_read_offset_prefer_base_offset_moves_from_dst_not_hour
1158
- offsets = [
1159
- {:gmtoff => -100, :isdst => false, :abbrev => 'LMT'},
1160
- {:gmtoff => 1800, :isdst => false, :abbrev => 'XST'},
1161
- {:gmtoff => 1800, :isdst => true, :abbrev => 'XDT'},
1162
- {:gmtoff => 0, :isdst => false, :abbrev => 'XST'}]
1163
-
1164
- transitions = [
1165
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
1166
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
1167
- {:at => Time.utc(2000, 3, 1), :offset_index => 3}]
1168
-
1169
- tzif_test(offsets, transitions) do |path, format|
1170
- info = ZoneinfoTimezoneInfo.new('Zone/BaseOffsetMovesFromDstNotHour', path)
1171
- assert_equal('Zone/BaseOffsetMovesFromDstNotHour', info.identifier)
1172
-
1173
- assert_period(:LMT, -100, 0, false, nil, Time.utc(2000, 1, 1), info)
1174
- assert_period(:XST, 1800, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
1175
- assert_period(:XDT, 0, 1800, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
1176
- assert_period(:XST, 0, 0, false, Time.utc(2000, 3, 1), nil, info)
1177
- end
1178
- end
1179
-
1180
- def test_load_in_safe_mode
1181
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
1182
-
1183
- tzif_test(offsets, []) do |path, format|
1184
- # untaint only required for Ruby 1.9.2
1185
- path.untaint
1186
-
1187
- safe_test do
1188
- info = ZoneinfoTimezoneInfo.new('Zone/three', path)
1189
- assert_equal('Zone/three', info.identifier)
1190
-
1191
- assert_period(:LT, -12094, 0, false, nil, nil, info)
1192
- end
1193
- end
1194
- end
1195
-
1196
- def test_load_encoding
1197
- # tzfile.5 doesn't specify an encoding, but the source data is in ASCII.
1198
- # ZoneinfoTimezoneInfo will load as UTF-8 (a superset of ASCII).
1199
-
1200
- offsets = [
1201
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
1202
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST©'}]
1203
-
1204
- transitions = [
1205
- {:at => Time.utc(1971, 1, 2), :offset_index => 1}]
1206
-
1207
- tzif_test(offsets, transitions) do |path, format|
1208
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
1209
- assert_equal('Zone/One', info.identifier)
1210
-
1211
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1971, 1, 2), info)
1212
- assert_period(:"XST©", 3600, 0, false, Time.utc(1971, 1, 2), nil, info)
1213
- end
1214
- end
1215
-
1216
- def test_load_binmode
1217
- offsets = [
1218
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
1219
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
1220
-
1221
- # Transition time that includes CRLF (4EFF0D0A).
1222
- # Test that this doesn't get corrupted by translating CRLF to LF.
1223
- transitions = [
1224
- {:at => Time.utc(2011, 12, 31, 13, 24, 26), :offset_index => 1}]
1225
-
1226
- tzif_test(offsets, transitions) do |path, format|
1227
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
1228
- assert_equal('Zone/One', info.identifier)
1229
-
1230
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2011, 12, 31, 13, 24, 26), info)
1231
- assert_period(:XST, 3600, 0, false, Time.utc(2011, 12, 31, 13, 24, 26), nil, info)
1232
- end
1233
- end
1234
- end