tzinfo 1.2.7 → 2.0.2

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