tzinfo 1.2.5 → 2.0.5

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