tzinfo 1.2.7 → 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 +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