tzinfo 1.2.1 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +3 -0
  4. data/CHANGES.md +693 -315
  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 +148 -120
  9. data/lib/tzinfo/country_timezone.rb +71 -101
  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 +997 -473
  46. data/lib/tzinfo/timezone_offset.rb +91 -54
  47. data/lib/tzinfo/timezone_period.rb +163 -188
  48. data/lib/tzinfo/timezone_proxy.rb +75 -49
  49. data/lib/tzinfo/timezone_transition.rb +77 -99
  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 -120
  58. metadata.gz.sig +0 -0
  59. data/Rakefile +0 -104
  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 -70
  67. data/lib/tzinfo/ruby_data_source.rb +0 -136
  68. data/lib/tzinfo/time_or_datetime.rb +0 -333
  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 -101
  73. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  74. data/lib/tzinfo/zoneinfo_country_info.rb +0 -35
  75. data/lib/tzinfo/zoneinfo_data_source.rb +0 -460
  76. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -245
  77. data/test/tc_country.rb +0 -236
  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 -161
  81. data/test/tc_data_source.rb +0 -192
  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 -80
  90. data/test/tc_ruby_data_source.rb +0 -143
  91. data/test/tc_time_or_datetime.rb +0 -639
  92. data/test/tc_timezone.rb +0 -1334
  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 -548
  101. data/test/tc_timezone_proxy.rb +0 -113
  102. data/test/tc_timezone_transition.rb +0 -352
  103. data/test/tc_timezone_transition_definition.rb +0 -284
  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 -64
  107. data/test/tc_zoneinfo_data_source.rb +0 -985
  108. data/test/tc_zoneinfo_timezone_info.rb +0 -814
  109. data/test/test_utils.rb +0 -132
  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 -594
  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/posix/Europe/London +0 -0
  143. data/test/zoneinfo/posixrules +0 -0
  144. data/test/zoneinfo/right/Europe/London +0 -0
  145. data/test/zoneinfo/zone.tab +0 -452
  146. data/tzinfo.gemspec +0 -21
@@ -1,814 +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_invalid_offset_index
290
- offsets = [{:gmtoff => -0, :isdst => false, :abbrev => 'LMT'}]
291
- transitions = [{:at => Time.utc(2000, 12, 31), :offset_index => 2}]
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_with_leap_seconds
301
- offsets = [{:gmtoff => -0, :isdst => false, :abbrev => 'LMT'}]
302
- leaps = [{:at => Time.utc(1972,6,30,23,59,60), :seconds => 1}]
303
-
304
- tzif_test(offsets, [], leaps) do |path, format|
305
- assert_raises(InvalidZoneinfoFile) do
306
- ZoneinfoTimezoneInfo.new('Zone', path)
307
- end
308
- end
309
- end
310
-
311
- def test_load_invalid_magic
312
- ['TZif4', 'tzif2', '12345'].each do |magic|
313
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
314
-
315
- tzif_test(offsets, [], [], :magic => magic) do |path, format|
316
- assert_raises(InvalidZoneinfoFile) do
317
- ZoneinfoTimezoneInfo.new('Zone2', path)
318
- end
319
- end
320
- end
321
- end
322
-
323
- # These tests can only be run if the platform supports 64-bit Times. When
324
- # 64-bit support is unavailable, the second section will not be read, so no
325
- # error will be raised.
326
- if SUPPORTS_64BIT
327
- def test_load_invalid_section2_magic
328
- ['TZif4', 'tzif2', '12345'].each do |section2_magic|
329
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
330
-
331
- tzif_test(offsets, [], [], :min_format => 2, :section2_magic => section2_magic) do |path, format|
332
- assert_raises(InvalidZoneinfoFile) do
333
- ZoneinfoTimezoneInfo.new('Zone4', path)
334
- end
335
- end
336
- end
337
- end
338
-
339
- def test_load_mismatched_section2_magic
340
- minus_one = Proc.new {|f| f == 2 ? "TZif\0" : "TZif#{f - 1}" }
341
- plus_one = Proc.new {|f| "TZif#{f + 1}" }
342
-
343
- [minus_one, plus_one].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('Zone5', path)
349
- end
350
- end
351
- end
352
- end
353
- end
354
-
355
- def test_load_invalid_format
356
- Tempfile.open('tzinfo-test-zone') do |file|
357
- file.write('Invalid')
358
- file.flush
359
-
360
- assert_raises(InvalidZoneinfoFile) do
361
- ZoneinfoTimezoneInfo.new('Zone3', file.path)
362
- end
363
- end
364
- end
365
-
366
- def test_load_missing_abbrev_null_termination
367
- offsets = [
368
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
369
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
370
-
371
- transitions = [
372
- {:at => Time.utc(2000, 1, 1), :offset_index => 1}]
373
-
374
- tzif_test(offsets, transitions, [], :abbrev_separator => '^') do |path, format|
375
- assert_raises(InvalidZoneinfoFile) do
376
- ZoneinfoTimezoneInfo.new('Zone', path)
377
- end
378
- end
379
- end
380
-
381
- def test_load_out_of_range_abbrev_offsets
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_offset_base => 8) do |path, format|
390
- assert_raises(InvalidZoneinfoFile) do
391
- ZoneinfoTimezoneInfo.new('Zone', path)
392
- end
393
- end
394
- end
395
-
396
- def test_load_before_epoch
397
- # Some platforms don't support negative timestamps for times before the
398
- # epoch. Check that they are returned when supported and skipped when not.
399
-
400
- # Note the last transition before the epoch (and within the 32-bit range) is
401
- # moved to the epoch on platforms that do not support negative timestamps.
402
-
403
- offsets = [
404
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
405
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
406
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
407
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
408
-
409
- transitions = [
410
- {:at => -694224000, :offset_index => 1}, # Time.utc(1948, 1, 2)
411
- {:at => -21945600, :offset_index => 2}, # Time.utc(1969, 4, 22)
412
- {:at => Time.utc(1970, 10, 21), :offset_index => 1},
413
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
414
-
415
- tzif_test(offsets, transitions) do |path, format|
416
- info = ZoneinfoTimezoneInfo.new('Zone/Negative', path)
417
- assert_equal('Zone/Negative', info.identifier)
418
-
419
- if SUPPORTS_NEGATIVE
420
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1948, 1, 2), info)
421
- assert_period(:XST, 3600, 0, false, Time.utc(1948, 1, 2), Time.utc(1969, 4, 22), info)
422
- assert_period(:XDT, 3600, 3600, true, Time.utc(1969, 4, 22), Time.utc(1970, 10, 21), info)
423
- else
424
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1970, 1, 1), info)
425
- assert_period(:XDT, 3600, 3600, true, Time.utc(1970, 1, 1), Time.utc(1970, 10, 21), info)
426
- end
427
-
428
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 10, 21), Time.utc(2000, 12, 31), info)
429
- assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
430
- end
431
- end
432
-
433
- def test_load_on_epoch
434
- offsets = [
435
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
436
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
437
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
438
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
439
-
440
- transitions = [
441
- {:at => -694224000, :offset_index => 1}, # Time.utc(1948, 1, 2)
442
- {:at => -21945600, :offset_index => 2}, # Time.utc(1969, 4, 22)
443
- {:at => Time.utc(1970, 1, 1), :offset_index => 1},
444
- {:at => Time.utc(2000, 12, 31), :offset_index => 3}]
445
-
446
- tzif_test(offsets, transitions) do |path, format|
447
- info = ZoneinfoTimezoneInfo.new('Zone/Negative', path)
448
- assert_equal('Zone/Negative', info.identifier)
449
-
450
- if SUPPORTS_NEGATIVE
451
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1948, 1, 2), info)
452
- assert_period(:XST, 3600, 0, false, Time.utc(1948, 1, 2), Time.utc(1969, 4, 22), info)
453
- assert_period(:XDT, 3600, 3600, true, Time.utc(1969, 4, 22), Time.utc(1970, 1, 1), info)
454
- else
455
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1970, 1, 1), info)
456
- end
457
-
458
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 1, 1), Time.utc(2000, 12, 31), info)
459
- assert_period(:XNST, 0, 0, false, Time.utc(2000, 12, 31), nil, info)
460
- end
461
- end
462
-
463
- def test_load_64bit
464
- # Some platforms support 64-bit Times, others only 32-bit. The TZif version
465
- # 2 and later format contains both 32-bit and 64-bit times.
466
-
467
- # Where 64-bit is supported and a TZif 2 or later file is provided, the
468
- # 64-bit times should be used, otherwise the 32-bit information should be
469
- # used.
470
-
471
- offsets = [
472
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
473
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
474
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
475
- {:gmtoff => 0, :isdst => false, :abbrev => 'XNST'}]
476
-
477
- transitions = [
478
- {:at => -3786739200, :offset_index => 1}, # Time.utc(1850, 1, 2)
479
- {:at => Time.utc(2003, 4, 22), :offset_index => 2},
480
- {:at => Time.utc(2003, 10, 21), :offset_index => 1},
481
- {:at => 2240524800, :offset_index => 3}] # Time.utc(2040, 12, 31)
482
-
483
- tzif_test(offsets, transitions) do |path, format|
484
- info = ZoneinfoTimezoneInfo.new('Zone/SixtyFour', path)
485
- assert_equal('Zone/SixtyFour', info.identifier)
486
-
487
- if SUPPORTS_64BIT && format >= 2
488
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1850, 1, 2), info)
489
- assert_period(:XST, 3600, 0, false, Time.utc(1850, 1, 2), Time.utc(2003, 4, 22), info)
490
- assert_period(:XDT, 3600, 3600, true, Time.utc(2003, 4, 22), Time.utc(2003, 10, 21), info)
491
- assert_period(:XST, 3600, 0, false, Time.utc(2003, 10, 21), Time.utc(2040, 12, 31), info)
492
- assert_period(:XNST, 0, 0, false, Time.utc(2040, 12, 31), nil, info)
493
- else
494
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2003, 4, 22), info)
495
- assert_period(:XDT, 3600, 3600, true, Time.utc(2003, 4, 22), Time.utc(2003, 10, 21), info)
496
- assert_period(:XST, 3600, 0, false, Time.utc(2003, 10, 21), nil, info)
497
- end
498
- end
499
- end
500
-
501
- def test_load_64bit_range
502
- # The full range of 64 bit timestamps is not currently supported because of
503
- # the way transitions are indexed. Transitions outside the supported range
504
- # will be ignored.
505
-
506
- offsets = [
507
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
508
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
509
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
510
-
511
- transitions = [
512
- {:at => -2**63, :offset_index => 1},
513
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
514
- {:at => 2**63 - 1, :offset_index => 0}]
515
-
516
- tzif_test(offsets, transitions) do |path, format|
517
- info = ZoneinfoTimezoneInfo.new('Zone/SixtyFourRange', path)
518
- assert_equal('Zone/SixtyFourRange', info.identifier)
519
-
520
- if SUPPORTS_64BIT && format >= 2
521
- # When the full range is supported, the following periods will be defined:
522
- #assert_period(:LMT, 3542, 0, false, nil, Time.at(-2**63).utc, info)
523
- #assert_period(:XST, 3600, 0, false, Time.at(-2**63).utc, Time.utc(2014, 5, 27), info)
524
- #assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**63 - 1).utc, info)
525
- #assert_period(:LMT, 3542, 0, false, Time.at(2**63 - 1).utc, nil, info)
526
-
527
- # Without full range support, the following periods will be defined:
528
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
529
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
530
- else
531
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
532
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
533
- end
534
- end
535
- end
536
-
537
- def test_load_supported_64bit_range
538
- # The full range of 64 bit timestamps is not currently supported because of
539
- # the way transitions are indexed. Transitions outside the supported range
540
- # will be ignored.
541
-
542
- min_timestamp = -8520336000 # Time.utc(1700, 1, 1).to_i
543
- max_timestamp = 16725225600 # Time.utc(2500, 1, 1).to_i
544
-
545
- offsets = [
546
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
547
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
548
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
549
-
550
- transitions = [
551
- {:at => min_timestamp, :offset_index => 1},
552
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
553
- {:at => max_timestamp - 1, :offset_index => 0}]
554
-
555
- tzif_test(offsets, transitions) do |path, format|
556
- info = ZoneinfoTimezoneInfo.new('Zone/SupportedSixtyFourRange', path)
557
- assert_equal('Zone/SupportedSixtyFourRange', info.identifier)
558
-
559
- if SUPPORTS_64BIT && format >= 2
560
- assert_period(:LMT, 3542, 0, false, nil, Time.at(min_timestamp).utc, info)
561
- assert_period(:XST, 3600, 0, false, Time.at(min_timestamp).utc, Time.utc(2014, 5, 27), info)
562
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(max_timestamp - 1).utc, info)
563
- assert_period(:LMT, 3542, 0, false, Time.at(max_timestamp - 1).utc, nil, info)
564
- else
565
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2014, 5, 27), info)
566
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), nil, info)
567
- end
568
- end
569
- end
570
-
571
- def test_load_32bit_range
572
- offsets = [
573
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
574
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
575
- {:gmtoff => 7200, :isdst => false, :abbrev => 'XNST'}]
576
-
577
- transitions = [
578
- {:at => -2**31, :offset_index => 1},
579
- {:at => Time.utc(2014, 5, 27), :offset_index => 2},
580
- {:at => 2**31 - 1, :offset_index => 0}]
581
-
582
- tzif_test(offsets, transitions) do |path, format|
583
- info = ZoneinfoTimezoneInfo.new('Zone/ThirtyTwoRange', path)
584
- assert_equal('Zone/ThirtyTwoRange', info.identifier)
585
-
586
- if SUPPORTS_NEGATIVE
587
- assert_period(:LMT, 3542, 0, false, nil, Time.at(-2**31).utc, info)
588
- assert_period(:XST, 3600, 0, false, Time.at(-2**31).utc, Time.utc(2014, 5, 27), info)
589
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**31 - 1).utc, info)
590
- assert_period(:LMT, 3542, 0, false, Time.at(2**31 - 1).utc, nil, info)
591
- else
592
- assert_period(:XST, 3600, 0, false, Time.utc(1970, 1, 1), Time.utc(2014, 5, 27), info)
593
- assert_period(:XNST, 7200, 0, false, Time.utc(2014, 5, 27), Time.at(2**31 - 1).utc, info)
594
- assert_period(:LMT, 3542, 0, false, Time.at(2**31 - 1).utc, nil, info)
595
- end
596
- end
597
- end
598
-
599
- def test_load_std_offset_changes
600
- # The zoneinfo files don't include the offset from standard time, so this
601
- # has to be derived by looking at changes in the total UTC offset.
602
-
603
- offsets = [
604
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
605
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
606
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
607
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
608
-
609
- transitions = [
610
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
611
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
612
- {:at => Time.utc(2000, 3, 1), :offset_index => 3},
613
- {:at => Time.utc(2000, 4, 1), :offset_index => 1}]
614
-
615
- tzif_test(offsets, transitions) do |path, format|
616
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
617
- assert_equal('Zone/DoubleDaylight', info.identifier)
618
-
619
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
620
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
621
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
622
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
623
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 4, 1), nil, info)
624
- end
625
- end
626
-
627
- def test_load_std_offset_changes_jump_to_double_dst
628
- # The zoneinfo files don't include the offset from standard time, so this
629
- # has to be derived by looking at changes in the total UTC offset.
630
-
631
- offsets = [
632
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
633
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
634
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
635
-
636
- transitions = [
637
- {:at => Time.utc(2000, 4, 1), :offset_index => 1},
638
- {:at => Time.utc(2000, 5, 1), :offset_index => 2},
639
- {:at => Time.utc(2000, 6, 1), :offset_index => 1}]
640
-
641
- tzif_test(offsets, transitions) do |path, format|
642
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
643
- assert_equal('Zone/DoubleDaylight', info.identifier)
644
-
645
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 4, 1), info)
646
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
647
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
648
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 6, 1), nil, info)
649
- end
650
- end
651
-
652
- def test_load_std_offset_changes_negative
653
- # The zoneinfo files don't include the offset from standard time, so this
654
- # has to be derived by looking at changes in the total UTC offset.
655
-
656
- offsets = [
657
- {:gmtoff => -10821, :isdst => false, :abbrev => 'LMT'},
658
- {:gmtoff => -10800, :isdst => false, :abbrev => 'XST'},
659
- {:gmtoff => -7200, :isdst => true, :abbrev => 'XDT'},
660
- {:gmtoff => -3600, :isdst => true, :abbrev => 'XDDT'}]
661
-
662
- transitions = [
663
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
664
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
665
- {:at => Time.utc(2000, 3, 1), :offset_index => 3},
666
- {:at => Time.utc(2000, 4, 1), :offset_index => 1},
667
- {:at => Time.utc(2000, 5, 1), :offset_index => 3},
668
- {:at => Time.utc(2000, 6, 1), :offset_index => 1}]
669
-
670
- tzif_test(offsets, transitions) do |path, format|
671
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
672
- assert_equal('Zone/DoubleDaylight', info.identifier)
673
-
674
- assert_period(:LMT, -10821, 0, false, nil, Time.utc(2000, 1, 1), info)
675
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
676
- assert_period(:XDT, -10800, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
677
- assert_period(:XDDT, -10800, 7200, true, Time.utc(2000, 3, 1), Time.utc(2000, 4, 1), info)
678
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 4, 1), Time.utc(2000, 5, 1), info)
679
- assert_period(:XDDT, -10800, 7200, true, Time.utc(2000, 5, 1), Time.utc(2000, 6, 1), info)
680
- assert_period(:XST, -10800, 0, false, Time.utc(2000, 6, 1), nil, info)
681
- end
682
- end
683
-
684
- def test_load_starts_two_hour_std_offset
685
- # The zoneinfo files don't include the offset from standard time, so this
686
- # has to be derived by looking at changes in the total UTC offset.
687
-
688
- offsets = [
689
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
690
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'},
691
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDT'},
692
- {:gmtoff => 10800, :isdst => true, :abbrev => 'XDDT'}]
693
-
694
- transitions = [
695
- {:at => Time.utc(2000, 1, 1), :offset_index => 3},
696
- {:at => Time.utc(2000, 2, 1), :offset_index => 2},
697
- {:at => Time.utc(2000, 3, 1), :offset_index => 1}]
698
-
699
- tzif_test(offsets, transitions) do |path, format|
700
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
701
- assert_equal('Zone/DoubleDaylight', info.identifier)
702
-
703
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
704
- assert_period(:XDDT, 3600, 7200, true, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
705
- assert_period(:XDT, 3600, 3600, true, Time.utc(2000, 2, 1), Time.utc(2000, 3, 1), info)
706
- assert_period(:XST, 3600, 0, false, Time.utc(2000, 3, 1), nil, info)
707
- end
708
- end
709
-
710
- def test_load_starts_all_same_dst_offset
711
- # The zoneinfo files don't include the offset from standard time, so this
712
- # has to be derived by looking at changes in the total UTC offset.
713
- #
714
- # If there are no changes in the UTC offset (ignoring the first offset,
715
- # which is usually local mean time), then a value of 1 hour is used as the
716
- # standard time offset.
717
-
718
- offsets = [
719
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
720
- {:gmtoff => 7200, :isdst => true, :abbrev => 'XDDT'}]
721
-
722
- transitions = [
723
- {:at => Time.utc(2000, 1, 1), :offset_index => 1}]
724
-
725
- tzif_test(offsets, transitions) do |path, format|
726
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
727
- assert_equal('Zone/DoubleDaylight', info.identifier)
728
-
729
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
730
- assert_period(:XDDT, 3600, 3600, true, Time.utc(2000, 1, 1), nil, info)
731
- end
732
- end
733
-
734
- def test_load_switch_to_dst_and_change_utc_offset
735
- # The zoneinfo files don't include the offset from standard time, so this
736
- # has to be derived by looking at changes in the total UTC offset.
737
-
738
- # Switch from non-DST to DST at the same time as moving the UTC offset
739
- # back an hour (i.e. wall clock time doesn't change).
740
-
741
- offsets = [
742
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
743
- {:gmtoff => 3600, :isdst => false, :abbrev => 'YST'},
744
- {:gmtoff => 3600, :isdst => true, :abbrev => 'XDT'}]
745
-
746
- transitions = [
747
- {:at => Time.utc(2000, 1, 1), :offset_index => 1},
748
- {:at => Time.utc(2000, 2, 1), :offset_index => 2}]
749
-
750
- tzif_test(offsets, transitions) do |path, format|
751
- info = ZoneinfoTimezoneInfo.new('Zone/DoubleDaylight', path)
752
- assert_equal('Zone/DoubleDaylight', info.identifier)
753
-
754
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2000, 1, 1), info)
755
- assert_period(:YST, 3600, 0, false, Time.utc(2000, 1, 1), Time.utc(2000, 2, 1), info)
756
- assert_period(:XDT, 0, 3600, true, Time.utc(2000, 2, 1), nil, info)
757
- end
758
- end
759
-
760
- def test_load_in_safe_mode
761
- offsets = [{:gmtoff => -12094, :isdst => false, :abbrev => 'LT'}]
762
-
763
- tzif_test(offsets, []) do |path, format|
764
- # untaint only required for Ruby 1.9.2
765
- path.untaint
766
-
767
- safe_test do
768
- info = ZoneinfoTimezoneInfo.new('Zone/three', path)
769
- assert_equal('Zone/three', info.identifier)
770
-
771
- assert_period(:LT, -12094, 0, false, nil, nil, info)
772
- end
773
- end
774
- end
775
-
776
- def test_load_encoding
777
- # tzfile.5 doesn't specify an encoding, but the source data is in ASCII.
778
- # ZoneinfoTimezoneInfo will load as UTF-8 (a superset of ASCII).
779
-
780
- offsets = [
781
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
782
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST©'}]
783
-
784
- transitions = [
785
- {:at => Time.utc(1971, 1, 2), :offset_index => 1}]
786
-
787
- tzif_test(offsets, transitions) do |path, format|
788
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
789
- assert_equal('Zone/One', info.identifier)
790
-
791
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(1971, 1, 2), info)
792
- assert_period(:"XST©", 3600, 0, false, Time.utc(1971, 1, 2), nil, info)
793
- end
794
- end
795
-
796
- def test_load_binmode
797
- offsets = [
798
- {:gmtoff => 3542, :isdst => false, :abbrev => 'LMT'},
799
- {:gmtoff => 3600, :isdst => false, :abbrev => 'XST'}]
800
-
801
- # Transition time that includes CRLF (4EFF0D0A).
802
- # Test that this doesn't get corrupted by translating CRLF to LF.
803
- transitions = [
804
- {:at => Time.utc(2011, 12, 31, 13, 24, 26), :offset_index => 1}]
805
-
806
- tzif_test(offsets, transitions) do |path, format|
807
- info = ZoneinfoTimezoneInfo.new('Zone/One', path)
808
- assert_equal('Zone/One', info.identifier)
809
-
810
- assert_period(:LMT, 3542, 0, false, nil, Time.utc(2011, 12, 31, 13, 24, 26), info)
811
- assert_period(:XST, 3600, 0, false, Time.utc(2011, 12, 31, 13, 24, 26), nil, info)
812
- end
813
- end
814
- end