tzinfo 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +1 -0
  4. data/.yardopts +6 -0
  5. data/CHANGES.md +797 -0
  6. data/LICENSE +19 -0
  7. data/README.md +152 -0
  8. data/Rakefile +107 -0
  9. data/lib/tzinfo.rb +40 -0
  10. data/lib/tzinfo/country.rb +196 -0
  11. data/lib/tzinfo/country_index_definition.rb +31 -0
  12. data/lib/tzinfo/country_info.rb +42 -0
  13. data/lib/tzinfo/country_timezone.rb +135 -0
  14. data/lib/tzinfo/data_source.rb +190 -0
  15. data/lib/tzinfo/data_timezone.rb +58 -0
  16. data/lib/tzinfo/data_timezone_info.rb +55 -0
  17. data/lib/tzinfo/info_timezone.rb +30 -0
  18. data/lib/tzinfo/linked_timezone.rb +63 -0
  19. data/lib/tzinfo/linked_timezone_info.rb +26 -0
  20. data/lib/tzinfo/offset_rationals.rb +77 -0
  21. data/lib/tzinfo/ruby_core_support.rb +176 -0
  22. data/lib/tzinfo/ruby_country_info.rb +74 -0
  23. data/lib/tzinfo/ruby_data_source.rb +138 -0
  24. data/lib/tzinfo/time_or_datetime.rb +340 -0
  25. data/lib/tzinfo/timezone.rb +673 -0
  26. data/lib/tzinfo/timezone_definition.rb +36 -0
  27. data/lib/tzinfo/timezone_index_definition.rb +54 -0
  28. data/lib/tzinfo/timezone_info.rb +30 -0
  29. data/lib/tzinfo/timezone_offset.rb +101 -0
  30. data/lib/tzinfo/timezone_period.rb +245 -0
  31. data/lib/tzinfo/timezone_proxy.rb +105 -0
  32. data/lib/tzinfo/timezone_transition.rb +130 -0
  33. data/lib/tzinfo/timezone_transition_definition.rb +104 -0
  34. data/lib/tzinfo/transition_data_timezone_info.rb +274 -0
  35. data/lib/tzinfo/zoneinfo_country_info.rb +37 -0
  36. data/lib/tzinfo/zoneinfo_data_source.rb +496 -0
  37. data/lib/tzinfo/zoneinfo_timezone_info.rb +298 -0
  38. data/test/tc_country.rb +236 -0
  39. data/test/tc_country_index_definition.rb +69 -0
  40. data/test/tc_country_info.rb +16 -0
  41. data/test/tc_country_timezone.rb +173 -0
  42. data/test/tc_data_source.rb +218 -0
  43. data/test/tc_data_timezone.rb +99 -0
  44. data/test/tc_data_timezone_info.rb +18 -0
  45. data/test/tc_info_timezone.rb +34 -0
  46. data/test/tc_linked_timezone.rb +155 -0
  47. data/test/tc_linked_timezone_info.rb +23 -0
  48. data/test/tc_offset_rationals.rb +23 -0
  49. data/test/tc_ruby_core_support.rb +168 -0
  50. data/test/tc_ruby_country_info.rb +110 -0
  51. data/test/tc_ruby_data_source.rb +165 -0
  52. data/test/tc_time_or_datetime.rb +660 -0
  53. data/test/tc_timezone.rb +1359 -0
  54. data/test/tc_timezone_definition.rb +113 -0
  55. data/test/tc_timezone_index_definition.rb +73 -0
  56. data/test/tc_timezone_info.rb +11 -0
  57. data/test/tc_timezone_london.rb +143 -0
  58. data/test/tc_timezone_melbourne.rb +142 -0
  59. data/test/tc_timezone_new_york.rb +142 -0
  60. data/test/tc_timezone_offset.rb +126 -0
  61. data/test/tc_timezone_period.rb +555 -0
  62. data/test/tc_timezone_proxy.rb +136 -0
  63. data/test/tc_timezone_transition.rb +366 -0
  64. data/test/tc_timezone_transition_definition.rb +295 -0
  65. data/test/tc_timezone_utc.rb +27 -0
  66. data/test/tc_transition_data_timezone_info.rb +433 -0
  67. data/test/tc_zoneinfo_country_info.rb +78 -0
  68. data/test/tc_zoneinfo_data_source.rb +1204 -0
  69. data/test/tc_zoneinfo_timezone_info.rb +1234 -0
  70. data/test/test_utils.rb +188 -0
  71. data/test/ts_all.rb +7 -0
  72. data/test/ts_all_ruby.rb +5 -0
  73. data/test/ts_all_zoneinfo.rb +9 -0
  74. data/test/tzinfo-data/tzinfo/data.rb +8 -0
  75. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +89 -0
  76. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +315 -0
  77. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +218 -0
  78. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +19 -0
  79. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +21 -0
  80. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +21 -0
  81. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +21 -0
  82. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +261 -0
  83. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +186 -0
  84. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +321 -0
  85. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +265 -0
  86. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +220 -0
  87. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +16 -0
  88. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +927 -0
  89. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +596 -0
  90. data/test/tzinfo-data/tzinfo/data/version.rb +14 -0
  91. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  92. data/test/zoneinfo/America/New_York +0 -0
  93. data/test/zoneinfo/Australia/Melbourne +0 -0
  94. data/test/zoneinfo/EST +0 -0
  95. data/test/zoneinfo/Etc/UTC +0 -0
  96. data/test/zoneinfo/Europe/Amsterdam +0 -0
  97. data/test/zoneinfo/Europe/Andorra +0 -0
  98. data/test/zoneinfo/Europe/London +0 -0
  99. data/test/zoneinfo/Europe/Paris +0 -0
  100. data/test/zoneinfo/Europe/Prague +0 -0
  101. data/test/zoneinfo/Factory +0 -0
  102. data/test/zoneinfo/iso3166.tab +275 -0
  103. data/test/zoneinfo/leapseconds +61 -0
  104. data/test/zoneinfo/posix/Europe/London +0 -0
  105. data/test/zoneinfo/posixrules +0 -0
  106. data/test/zoneinfo/right/Europe/London +0 -0
  107. data/test/zoneinfo/zone.tab +439 -0
  108. data/test/zoneinfo/zone1970.tab +369 -0
  109. data/tzinfo.gemspec +21 -0
  110. metadata +191 -0
  111. metadata.gz.sig +0 -0
@@ -0,0 +1,1359 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
2
+
3
+ include TZInfo
4
+
5
+ using TaintExt if Module.const_defined?(:TaintExt)
6
+
7
+ class TCTimezone < Minitest::Test
8
+
9
+ class BlockCalled < StandardError
10
+ end
11
+
12
+ class TestTimezone < Timezone
13
+ def self.new(identifier, period_for_utc = nil, periods_for_local = nil, expected = nil)
14
+ t = super()
15
+ t.send(:setup, identifier, period_for_utc, periods_for_local, expected)
16
+ t
17
+ end
18
+
19
+ def identifier
20
+ @identifier
21
+ end
22
+
23
+ def period_for_utc(utc)
24
+ utc = TimeOrDateTime.wrap(utc)
25
+ raise "Unexpected utc #{utc} in period_for_utc" unless @expected.eql?(utc)
26
+ @period_for_utc
27
+ end
28
+
29
+ def periods_for_local(local)
30
+ local = TimeOrDateTime.wrap(local)
31
+ raise "Unexpected local #{local} in periods_for_local" unless @expected.eql?(local)
32
+ @periods_for_local.clone
33
+ end
34
+
35
+ def transitions_up_to(utc_to, utc_from = nil)
36
+ raise 'transitions_up_to called'
37
+ end
38
+
39
+ private
40
+ def setup(identifier, period_for_utc, periods_for_local, expected)
41
+ @identifier = identifier
42
+ @period_for_utc = period_for_utc
43
+ @periods_for_local = periods_for_local || []
44
+ @expected = TimeOrDateTime.wrap(expected)
45
+ end
46
+ end
47
+
48
+ class OffsetsUpToTestTimezone < Timezone
49
+ def self.new(identifier, expected_utc_to, expected_utc_from, transitions_up_to)
50
+ t = super()
51
+ t.send(:setup, identifier, expected_utc_to, expected_utc_from, transitions_up_to)
52
+ t
53
+ end
54
+
55
+ def identifier
56
+ @identifier
57
+ end
58
+
59
+ def period_for_utc(utc)
60
+ raise 'period_for_utc called'
61
+ end
62
+
63
+ def periods_for_local(local)
64
+ raise 'periods_for_local called'
65
+ end
66
+
67
+ def transitions_up_to(utc_to, utc_from = nil)
68
+ utc_to = TimeOrDateTime.wrap(utc_to)
69
+ raise "Unexpected utc_to #{utc_to || 'nil'} in transitions_up_to" unless @expected_utc_to.eql?(utc_to)
70
+
71
+ utc_from = utc_from ? TimeOrDateTime.wrap(utc_from) : nil
72
+ raise "Unexpected utc_from #{utc_from || 'nil'} in transitions_up_to" unless @expected_utc_from.eql?(utc_from)
73
+
74
+ if utc_from && utc_to <= utc_from
75
+ raise ArgumentError, 'utc_to must be greater than utc_from'
76
+ end
77
+
78
+ @transitions_up_to
79
+ end
80
+
81
+ private
82
+
83
+ def setup(identifier, expected_utc_to, expected_utc_from, transitions_up_to)
84
+ @identifier = identifier
85
+ @expected_utc_to = TimeOrDateTime.wrap(expected_utc_to)
86
+ @expected_utc_from = expected_utc_from ? TimeOrDateTime.wrap(expected_utc_from) : nil
87
+ @transitions_up_to = transitions_up_to
88
+ end
89
+ end
90
+
91
+ class OffsetsUpToNoTransitionsTestTimezone < Timezone
92
+ def self.new(identifier, expected_utc_to, expected_utc_from, period_for_utc)
93
+ t = super()
94
+ t.send(:setup, identifier, expected_utc_to, expected_utc_from, period_for_utc)
95
+ t
96
+ end
97
+
98
+ def identifier
99
+ @identifier
100
+ end
101
+
102
+ def period_for_utc(utc)
103
+ utc = TimeOrDateTime.wrap(utc)
104
+
105
+ raise "Unexpected utc #{utc} in period_for_utc (should be utc_from)" if @expected_utc_from && !@expected_utc_from.eql?(utc)
106
+ raise "Unexpected utc #{utc} in period_for_utc (should be < utc_to)" if !@expected_utc_from && @expected_utc_to <= utc
107
+
108
+ @period_for_utc
109
+ end
110
+
111
+ def periods_for_local(local)
112
+ raise 'periods_for_local called'
113
+ end
114
+
115
+ def transitions_up_to(utc_to, utc_from = nil)
116
+ utc_to = TimeOrDateTime.wrap(utc_to)
117
+ raise "Unexpected utc_to #{utc_to || 'nil'} in transitions_up_to" unless @expected_utc_to.eql?(utc_to)
118
+
119
+ utc_from = utc_from ? TimeOrDateTime.wrap(utc_from) : nil
120
+ raise "Unexpected utc_from #{utc_from || 'nil'} in transitions_up_to" unless @expected_utc_from.eql?(utc_from)
121
+
122
+ if utc_from && utc_to <= utc_from
123
+ raise ArgumentError, 'utc_to must be greater than utc_from'
124
+ end
125
+
126
+ []
127
+ end
128
+
129
+ private
130
+
131
+ def setup(identifier, expected_utc_to, expected_utc_from, period_for_utc)
132
+ @identifier = identifier
133
+ @expected_utc_to = TimeOrDateTime.wrap(expected_utc_to)
134
+ @expected_utc_from = expected_utc_from ? TimeOrDateTime.wrap(expected_utc_from) : nil
135
+ @period_for_utc = period_for_utc
136
+ end
137
+ end
138
+
139
+ class TestTimezoneTransition < TimezoneTransition
140
+ def initialize(offset, previous_offset, at)
141
+ super(offset, previous_offset)
142
+ @at = TimeOrDateTime.wrap(at)
143
+ end
144
+
145
+ def at
146
+ @at
147
+ end
148
+ end
149
+
150
+ def setup
151
+ @orig_default_dst = Timezone.default_dst
152
+ @orig_data_source = DataSource.get
153
+ Timezone.send :init_loaded_zones
154
+ end
155
+
156
+ def teardown
157
+ Timezone.default_dst = @orig_default_dst
158
+ DataSource.set(@orig_data_source)
159
+ end
160
+
161
+ def test_default_dst_initial_value
162
+ assert_nil(Timezone.default_dst)
163
+ end
164
+
165
+ def test_set_default_dst
166
+ Timezone.default_dst = true
167
+ assert_equal(true, Timezone.default_dst)
168
+ Timezone.default_dst = false
169
+ assert_equal(false, Timezone.default_dst)
170
+ Timezone.default_dst = nil
171
+ assert_nil(Timezone.default_dst)
172
+ Timezone.default_dst = 0
173
+ assert_equal(true, Timezone.default_dst)
174
+ end
175
+
176
+ def test_get_valid_1
177
+ tz = Timezone.get('Europe/London')
178
+
179
+ assert_kind_of(DataTimezone, tz)
180
+ assert_equal('Europe/London', tz.identifier)
181
+ end
182
+
183
+ def test_get_valid_2
184
+ tz = Timezone.get('UTC')
185
+
186
+ # ZoneinfoDataSource doesn't return LinkedTimezoneInfo for any timezone.
187
+ if DataSource.get.load_timezone_info('UTC').kind_of?(LinkedTimezoneInfo)
188
+ assert_kind_of(LinkedTimezone, tz)
189
+ else
190
+ assert_kind_of(DataTimezone, tz)
191
+ end
192
+
193
+ assert_equal('UTC', tz.identifier)
194
+ end
195
+
196
+ def test_get_valid_3
197
+ tz = Timezone.get('America/Argentina/Buenos_Aires')
198
+
199
+ assert_kind_of(DataTimezone, tz)
200
+ assert_equal('America/Argentina/Buenos_Aires', tz.identifier)
201
+ end
202
+
203
+ def test_get_same_instance
204
+ tz1 = Timezone.get('Europe/London')
205
+ tz2 = Timezone.get('Europe/London')
206
+ assert_same(tz1, tz2)
207
+ end
208
+
209
+ def test_get_not_exist
210
+ assert_raises(InvalidTimezoneIdentifier) { Timezone.get('Nowhere/Special') }
211
+ end
212
+
213
+ def test_get_invalid
214
+ assert_raises(InvalidTimezoneIdentifier) { Timezone.get('../Definitions/UTC') }
215
+ end
216
+
217
+ def test_get_nil
218
+ assert_raises(InvalidTimezoneIdentifier) { Timezone.get(nil) }
219
+ end
220
+
221
+ def test_get_case
222
+ Timezone.get('Europe/Prague')
223
+ assert_raises(InvalidTimezoneIdentifier) { Timezone.get('Europe/prague') }
224
+ end
225
+
226
+ def test_get_proxy_valid
227
+ proxy = Timezone.get_proxy('Europe/London')
228
+ assert_kind_of(TimezoneProxy, proxy)
229
+ assert_equal('Europe/London', proxy.identifier)
230
+ end
231
+
232
+ def test_get_proxy_not_exist
233
+ proxy = Timezone.get_proxy('Not/There')
234
+ assert_kind_of(TimezoneProxy, proxy)
235
+ assert_equal('Not/There', proxy.identifier)
236
+ end
237
+
238
+ def test_get_proxy_invalid
239
+ proxy = Timezone.get_proxy('../Invalid/Identifier')
240
+ assert_kind_of(TimezoneProxy, proxy)
241
+ assert_equal('../Invalid/Identifier', proxy.identifier)
242
+ end
243
+
244
+ def test_get_tainted_loaded
245
+ Timezone.get('Europe/Andorra')
246
+
247
+ safe_test(:unavailable => :skip) do
248
+ identifier = 'Europe/Andorra'.dup.taint
249
+ assert(identifier.tainted?)
250
+ tz = Timezone.get(identifier)
251
+ assert_equal('Europe/Andorra', tz.identifier)
252
+ assert(identifier.tainted?)
253
+ end
254
+ end
255
+
256
+ def test_get_tainted_and_frozen_loaded
257
+ Timezone.get('Europe/Andorra')
258
+
259
+ safe_test do
260
+ tz = Timezone.get('Europe/Andorra'.dup.taint.freeze)
261
+ assert_equal('Europe/Andorra', tz.identifier)
262
+ end
263
+ end
264
+
265
+ def test_get_tainted_not_previously_loaded
266
+ skip_if_has_bug_14060
267
+
268
+ safe_test(:unavailable => :skip) do
269
+ identifier = 'Europe/Andorra'.dup.taint
270
+ assert(identifier.tainted?)
271
+ tz = Timezone.get(identifier)
272
+ assert_equal('Europe/Andorra', tz.identifier)
273
+ assert(identifier.tainted?)
274
+ end
275
+ end
276
+
277
+ def test_get_tainted_and_frozen_not_previously_loaded
278
+ skip_if_has_bug_14060
279
+
280
+ safe_test do
281
+ tz = Timezone.get('Europe/Amsterdam'.dup.taint.freeze)
282
+ assert_equal('Europe/Amsterdam', tz.identifier)
283
+ end
284
+ end
285
+
286
+ def test_new_no_args
287
+ tz = Timezone.new
288
+
289
+ assert_raises(UnknownTimezone) { tz.identifier }
290
+ assert_raises(UnknownTimezone) { tz.friendly_identifier }
291
+ assert_raises(UnknownTimezone) { tz.utc_to_local(DateTime.new(2006,1,1,1,0,0)) }
292
+ assert_raises(UnknownTimezone) { tz.local_to_utc(DateTime.new(2006,1,1,1,0,0)) }
293
+ assert_raises(UnknownTimezone) { tz.period_for_utc(DateTime.new(2006,1,1,1,0,0)) }
294
+ assert_raises(UnknownTimezone) { tz.periods_for_local(DateTime.new(2006,1,1,1,0,0)) }
295
+ assert_raises(UnknownTimezone) { tz.period_for_local(DateTime.new(2006,1,1,1,0,0)) }
296
+ assert_raises(UnknownTimezone) { tz.now }
297
+ assert_raises(UnknownTimezone) { tz.current_period_and_time }
298
+ assert_raises(UnknownTimezone) { tz.transitions_up_to(DateTime.new(2006,1,1,1,0,0)) }
299
+ assert_raises(UnknownTimezone) { tz.canonical_identifier }
300
+ assert_raises(UnknownTimezone) { tz.canonical_zone }
301
+ end
302
+
303
+ def test_new_nil
304
+ tz = Timezone.new(nil)
305
+
306
+ assert_raises(UnknownTimezone) { tz.identifier }
307
+ assert_raises(UnknownTimezone) { tz.friendly_identifier }
308
+ assert_raises(UnknownTimezone) { tz.utc_to_local(DateTime.new(2006,1,1,1,0,0)) }
309
+ assert_raises(UnknownTimezone) { tz.local_to_utc(DateTime.new(2006,1,1,1,0,0)) }
310
+ assert_raises(UnknownTimezone) { tz.period_for_utc(DateTime.new(2006,1,1,1,0,0)) }
311
+ assert_raises(UnknownTimezone) { tz.periods_for_local(DateTime.new(2006,1,1,1,0,0)) }
312
+ assert_raises(UnknownTimezone) { tz.period_for_local(DateTime.new(2006,1,1,1,0,0)) }
313
+ assert_raises(UnknownTimezone) { tz.now }
314
+ assert_raises(UnknownTimezone) { tz.current_period_and_time }
315
+ assert_raises(UnknownTimezone) { tz.transitions_up_to(DateTime.new(2006,1,1,1,0,0)) }
316
+ assert_raises(UnknownTimezone) { tz.canonical_identifier }
317
+ assert_raises(UnknownTimezone) { tz.canonical_zone }
318
+ end
319
+
320
+ def test_new_arg
321
+ tz = Timezone.new('Europe/London')
322
+ assert_same(Timezone.get('Europe/London'), tz)
323
+ end
324
+
325
+ def test_new_arg_not_exist
326
+ assert_raises(InvalidTimezoneIdentifier) { Timezone.new('Nowhere/Special') }
327
+ end
328
+
329
+ def test_all
330
+ all = Timezone.all
331
+ expected = DataSource.get.timezone_identifiers.collect {|identifier| Timezone.get_proxy(identifier)}
332
+ assert_equal(expected, all)
333
+ end
334
+
335
+ def test_all_identifiers
336
+ all = Timezone.all_identifiers
337
+ assert_equal(DataSource.get.timezone_identifiers, all)
338
+ end
339
+
340
+ def test_all_data_zones
341
+ all_data = Timezone.all_data_zones
342
+ expected = DataSource.get.data_timezone_identifiers.collect {|identifier| Timezone.get_proxy(identifier)}
343
+ assert_equal(expected, all_data)
344
+ end
345
+
346
+ def test_all_data_zone_identifiers
347
+ all_data = Timezone.all_data_zone_identifiers
348
+ assert_equal(DataSource.get.data_timezone_identifiers, all_data)
349
+ end
350
+
351
+ def test_all_linked_zones
352
+ all_linked = Timezone.all_linked_zones
353
+ expected = DataSource.get.linked_timezone_identifiers.collect {|identifier| Timezone.get_proxy(identifier)}
354
+ assert_equal(expected, all_linked)
355
+ end
356
+
357
+ def test_all_linked_zone_identifiers
358
+ all_linked = Timezone.all_linked_zone_identifiers
359
+ assert_equal(DataSource.get.linked_timezone_identifiers, all_linked)
360
+ end
361
+
362
+ def test_all_country_zones
363
+ # Probably should relax this test - just need all the zones, don't care
364
+ # about order.
365
+ expected = Country.all.inject([]) {|result,country|
366
+ result += country.zones
367
+ }
368
+ expected.uniq!
369
+
370
+ all_country_zones = Timezone.all_country_zones
371
+ assert_equal(expected, all_country_zones)
372
+
373
+ all_country_zone_identifiers = Timezone.all_country_zone_identifiers
374
+ assert_equal(all_country_zone_identifiers.length, all_country_zones.length)
375
+
376
+ all_country_zones.each {|zone|
377
+ assert_kind_of(TimezoneProxy, zone)
378
+ assert(all_country_zone_identifiers.include?(zone.identifier))
379
+ }
380
+ end
381
+
382
+ def test_all_country_zone_identifiers
383
+ # Probably should relax this test - just need all the zones, don't care
384
+ # about order.
385
+ expected = Country.all.inject([]) {|result,country|
386
+ result += country.zone_identifiers
387
+ }
388
+ expected.uniq!
389
+
390
+ assert_equal(expected, Timezone.all_country_zone_identifiers)
391
+ end
392
+
393
+ def test_us_zones
394
+ # Probably should relax this test - just need all the zones, don't care
395
+ # about order.
396
+ us_zones = Timezone.us_zones
397
+ assert_equal(Country.get('US').zones.uniq, us_zones)
398
+
399
+ us_zone_identifiers = Timezone.us_zone_identifiers
400
+ assert_equal(us_zone_identifiers.length, us_zones.length)
401
+
402
+ us_zones.each {|zone|
403
+ assert_kind_of(TimezoneProxy, zone)
404
+ assert(us_zone_identifiers.include?(zone.identifier))
405
+ }
406
+ end
407
+
408
+ def test_us_zone_identifiers
409
+ # Probably should relax this test - just need all the zones, don't care
410
+ # about order.
411
+ assert_equal(Country.get('US').zone_identifiers.uniq, Timezone.us_zone_identifiers)
412
+ end
413
+
414
+ def test_identifier
415
+ assert_raises(UnknownTimezone) { Timezone.new.identifier }
416
+ assert_equal('Europe/Paris', TestTimezone.new('Europe/Paris').identifier)
417
+ end
418
+
419
+ def test_name
420
+ assert_raises(UnknownTimezone) { Timezone.new.name }
421
+ assert_equal('Europe/Paris', TestTimezone.new('Europe/Paris').name)
422
+ end
423
+
424
+ def test_friendly_identifier
425
+ assert_equal('Paris', TestTimezone.new('Europe/Paris').friendly_identifier(true))
426
+ assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').friendly_identifier(false))
427
+ assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').friendly_identifier)
428
+ assert_equal('Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier(true))
429
+ assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier(false))
430
+ assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier)
431
+ assert_equal('Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier(true))
432
+ assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier(false))
433
+ assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier)
434
+ assert_equal('McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier(true))
435
+ assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier(false))
436
+ assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier)
437
+ assert_equal('GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier(true))
438
+ assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier(false))
439
+ assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier)
440
+ assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier(true))
441
+ assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier(false))
442
+ assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier)
443
+ end
444
+
445
+ if defined?(Encoding)
446
+ def test_friendly_identifier_non_binary_encoding
447
+ refute_equal(Encoding::ASCII_8BIT, TestTimezone.new('Europe/Paris').friendly_identifier(true).encoding)
448
+ refute_equal(Encoding::ASCII_8BIT, TestTimezone.new('Europe/Paris').friendly_identifier(false).encoding)
449
+ end
450
+ end
451
+
452
+ def test_to_s
453
+ assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').to_s)
454
+ assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').to_s)
455
+ assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').to_s)
456
+ assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').to_s)
457
+ assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').to_s)
458
+ assert_equal('UTC', TestTimezone.new('UTC').to_s)
459
+ end
460
+
461
+ def test_period_for_local
462
+ dt = DateTime.new(2005,2,18,16,24,23)
463
+ dt2 = DateTime.new(2005,2,18,16,24,23).new_offset(Rational(5,24))
464
+ dt3 = DateTime.new(2005,2,18,16,24,23 + Rational(789, 1000))
465
+ t = Time.utc(2005,2,18,16,24,23)
466
+ t2 = Time.local(2005,2,18,16,24,23)
467
+ t3 = Time.utc(2005,2,18,16,24,23,789000)
468
+ ts = t.to_i
469
+
470
+ o1 = TimezoneOffset.new(0, 0, :GMT)
471
+ o2 = TimezoneOffset.new(0, 3600, :BST)
472
+
473
+ period = TimezonePeriod.new(
474
+ TestTimezoneTransition.new(o1, o2, 1099184400),
475
+ TestTimezoneTransition.new(o2, o1, 1111885200))
476
+
477
+ dt_period = TestTimezone.new('Europe/London', nil, [period], dt).period_for_local(dt)
478
+ dt2_period = TestTimezone.new('Europe/London', nil, [period], dt2).period_for_local(dt2)
479
+ dt3_period = TestTimezone.new('Europe/London', nil, [period], dt3).period_for_local(dt3)
480
+ t_period = TestTimezone.new('Europe/London', nil, [period], t).period_for_local(t)
481
+ t2_period = TestTimezone.new('Europe/London', nil, [period], t2).period_for_local(t2)
482
+ t3_period = TestTimezone.new('Europe/London', nil, [period], t3).period_for_local(t3)
483
+ ts_period = TestTimezone.new('Europe/London', nil, [period], ts).period_for_local(ts)
484
+
485
+ assert_equal(period, dt_period)
486
+ assert_equal(period, dt2_period)
487
+ assert_equal(period, dt3_period)
488
+ assert_equal(period, t_period)
489
+ assert_equal(period, t2_period)
490
+ assert_equal(period, t3_period)
491
+ assert_equal(period, ts_period)
492
+ end
493
+
494
+ def test_period_for_local_invalid
495
+ dt = DateTime.new(2004,4,4,2,30,0)
496
+ tz = TestTimezone.new('America/New_York', nil, [], dt)
497
+
498
+ assert_raises(PeriodNotFound) do
499
+ tz.period_for_local(dt)
500
+ end
501
+ end
502
+
503
+ def test_period_for_local_ambiguous
504
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
505
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
506
+
507
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
508
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
509
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
510
+
511
+ p1 = TimezonePeriod.new(t1, t2)
512
+ p2 = TimezonePeriod.new(t2, t3)
513
+
514
+ dt = DateTime.new(2004,10,31,1,0,0)
515
+ dt2 = DateTime.new(2004,10,31,1,0,Rational(555,1000))
516
+ t = Time.utc(2004,10,31,1,30,0)
517
+ t2 = Time.utc(2004,10,31,1,30,0,555000)
518
+ i = Time.utc(2004,10,31,1,59,59).to_i
519
+
520
+ dt_tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
521
+ dt2_tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt2)
522
+ t_tz = TestTimezone.new('America/New_York', nil, [p1, p2], t)
523
+ t2_tz = TestTimezone.new('America/New_York', nil, [p1, p2], t2)
524
+ i_tz = TestTimezone.new('America/New_York', nil, [p1, p2], i)
525
+
526
+ assert_raises(AmbiguousTime) { dt_tz.period_for_local(dt) }
527
+ assert_raises(AmbiguousTime) { dt2_tz.period_for_local(dt2) }
528
+ assert_raises(AmbiguousTime) { t_tz.period_for_local(t) }
529
+ assert_raises(AmbiguousTime) { t2_tz.period_for_local(t2) }
530
+ assert_raises(AmbiguousTime) { i_tz.period_for_local(i) }
531
+ end
532
+
533
+ def test_period_for_local_not_found
534
+ dt = DateTime.new(2004,4,4,2,0,0)
535
+ dt2 = DateTime.new(2004,4,4,2,0,Rational(987,1000))
536
+ t = Time.utc(2004,4,4,2,30,0)
537
+ t2 = Time.utc(2004,4,4,2,30,0,987000)
538
+ i = Time.utc(2004,4,4,2,59,59).to_i
539
+
540
+ dt_tz = TestTimezone.new('America/New_York', nil, [], dt)
541
+ dt2_tz = TestTimezone.new('America/New_York', nil, [], dt2)
542
+ t_tz = TestTimezone.new('America/New_York', nil, [], t)
543
+ t2_tz = TestTimezone.new('America/New_York', nil, [], t2)
544
+ i_tz = TestTimezone.new('America/New_York', nil, [], i)
545
+
546
+ assert_raises(PeriodNotFound) { dt_tz.period_for_local(dt) }
547
+ assert_raises(PeriodNotFound) { dt2_tz.period_for_local(dt2) }
548
+ assert_raises(PeriodNotFound) { t_tz.period_for_local(t) }
549
+ assert_raises(PeriodNotFound) { t2_tz.period_for_local(t2) }
550
+ assert_raises(PeriodNotFound) { i_tz.period_for_local(i) }
551
+ end
552
+
553
+ def test_period_for_local_default_dst_set_true
554
+ Timezone.default_dst = true
555
+
556
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
557
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
558
+
559
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
560
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
561
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
562
+
563
+ p1 = TimezonePeriod.new(t1, t2)
564
+ p2 = TimezonePeriod.new(t2, t3)
565
+
566
+ dt = DateTime.new(2004,10,31,1,30,0)
567
+
568
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
569
+
570
+ assert_equal(p1, tz.period_for_local(dt))
571
+ assert_equal(p1, tz.period_for_local(dt, true))
572
+ assert_equal(p2, tz.period_for_local(dt, false))
573
+ assert_raises(AmbiguousTime) { tz.period_for_local(dt, nil) }
574
+ end
575
+
576
+ def test_period_for_local_default_dst_set_false
577
+ Timezone.default_dst = false
578
+
579
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
580
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
581
+
582
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
583
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
584
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
585
+
586
+ p1 = TimezonePeriod.new(t1, t2)
587
+ p2 = TimezonePeriod.new(t2, t3)
588
+
589
+ dt = DateTime.new(2004,10,31,1,30,0)
590
+
591
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
592
+
593
+ assert_equal(p2, tz.period_for_local(dt))
594
+ assert_equal(p1, tz.period_for_local(dt, true))
595
+ assert_equal(p2, tz.period_for_local(dt, false))
596
+ assert_raises(AmbiguousTime) { tz.period_for_local(dt, nil) }
597
+ end
598
+
599
+ def test_period_for_local_dst_flag_resolved
600
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
601
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
602
+
603
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
604
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
605
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
606
+
607
+ p1 = TimezonePeriod.new(t1, t2)
608
+ p2 = TimezonePeriod.new(t2, t3)
609
+
610
+ dt = DateTime.new(2004,10,31,1,30,0)
611
+
612
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
613
+
614
+ assert_equal(p1, tz.period_for_local(dt, true))
615
+ assert_equal(p2, tz.period_for_local(dt, false))
616
+ assert_equal(p1, tz.period_for_local(dt, true) {|periods| raise BlockCalled, 'should not be called' })
617
+ assert_equal(p2, tz.period_for_local(dt, false) {|periods| raise BlockCalled, 'should not be called' })
618
+ end
619
+
620
+ def test_period_for_local_dst_block_called
621
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
622
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
623
+
624
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
625
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
626
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
627
+
628
+ p1 = TimezonePeriod.new(t1, t2)
629
+ p2 = TimezonePeriod.new(t2, t3)
630
+
631
+ dt = DateTime.new(2004,10,31,1,30,0)
632
+
633
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
634
+
635
+ assert_raises(BlockCalled) {
636
+ tz.period_for_local(dt) {|periods|
637
+ assert_equal([p1, p2], periods)
638
+
639
+ # raise exception to test that the block was called
640
+ raise BlockCalled, 'should be raised'
641
+ }
642
+ }
643
+
644
+ assert_equal(p1, tz.period_for_local(dt) {|periods| periods.first})
645
+ assert_equal(p2, tz.period_for_local(dt) {|periods| periods.last})
646
+ assert_equal(p1, tz.period_for_local(dt) {|periods| [periods.first]})
647
+ assert_equal(p2, tz.period_for_local(dt) {|periods| [periods.last]})
648
+ end
649
+
650
+ def test_period_for_local_dst_cannot_resolve
651
+ # At midnight local time on Aug 5 1915 in Warsaw, the clocks were put back
652
+ # 24 minutes and both periods were non-DST. Hence the block should be
653
+ # called regardless of the value of the Boolean dst parameter.
654
+
655
+ o0 = TimezoneOffset.new(5040, 0, :LMT)
656
+ o1 = TimezoneOffset.new(5040, 0, :WMT)
657
+ o2 = TimezoneOffset.new(3600, 0, :CET)
658
+ o3 = TimezoneOffset.new(3600, 3600, :CEST)
659
+
660
+ t1 = TestTimezoneTransition.new(o1, o0, DateTime.new(1879, 12, 31, 22, 36, 0))
661
+ t2 = TestTimezoneTransition.new(o2, o1, DateTime.new(1915, 8, 4, 22, 36, 0))
662
+ t3 = TestTimezoneTransition.new(o3, o2, DateTime.new(1916, 4, 30, 22, 0, 0))
663
+
664
+ p1 = TimezonePeriod.new(t1, t2)
665
+ p2 = TimezonePeriod.new(t2, t3)
666
+
667
+ dt = DateTime.new(1915,8,4,23,40,0)
668
+
669
+ tz = TestTimezone.new('Europe/Warsaw', nil, [p1, p2], dt)
670
+
671
+ assert_raises(BlockCalled) {
672
+ tz.period_for_local(dt, true) {|periods|
673
+ assert_equal([p1, p2], periods)
674
+ raise BlockCalled, 'should be raised'
675
+ }
676
+ }
677
+
678
+ assert_raises(BlockCalled) {
679
+ tz.period_for_local(dt, false) {|periods|
680
+ assert_equal([p1, p2], periods)
681
+ raise BlockCalled, 'should be raised'
682
+ }
683
+ }
684
+ end
685
+
686
+ def test_period_for_local_block_ambiguous
687
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
688
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
689
+
690
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
691
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
692
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
693
+
694
+ p1 = TimezonePeriod.new(t1, t2)
695
+ p2 = TimezonePeriod.new(t2, t3)
696
+
697
+ dt = DateTime.new(2004,10,31,1,30,0)
698
+
699
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
700
+
701
+ assert_raises(AmbiguousTime) do
702
+ tz.period_for_local(dt) {|periods| nil}
703
+ end
704
+
705
+ assert_raises(AmbiguousTime) do
706
+ tz.period_for_local(dt) {|periods| periods}
707
+ end
708
+
709
+ assert_raises(AmbiguousTime) do
710
+ tz.period_for_local(dt) {|periods| []}
711
+ end
712
+
713
+ assert_raises(AmbiguousTime) do
714
+ tz.period_for_local(dt) {|periods| raise AmbiguousTime, 'Ambiguous time'}
715
+ end
716
+ end
717
+
718
+ def test_utc_to_local
719
+ dt = DateTime.new(2005,6,18,16,24,23)
720
+ dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5,24))
721
+ dtu = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000))
722
+ dtu2 = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000)).new_offset(Rational(5,24))
723
+ t = Time.utc(2005,6,18,16,24,23)
724
+ t2 = Time.local(2005,6,18,16,24,23)
725
+ tu = Time.utc(2005,6,18,16,24,23,567000)
726
+ tu2 = Time.local(2005,6,18,16,24,23,567000)
727
+ ts = t.to_i
728
+
729
+ o1 = TimezoneOffset.new(0, 0, :GMT)
730
+ o2 = TimezoneOffset.new(0, 3600, :BST)
731
+
732
+ period = TimezonePeriod.new(
733
+ TestTimezoneTransition.new(o2, o1, 1111885200),
734
+ TestTimezoneTransition.new(o1, o2, 1130634000))
735
+
736
+ assert_equal(DateTime.new(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], dt).utc_to_local(dt))
737
+ assert_equal(DateTime.new(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], dt2).utc_to_local(dt2))
738
+ assert_equal(DateTime.new(2005,6,18,17,24,23 + Rational(567,1000)), TestTimezone.new('Europe/London', period, [], dtu).utc_to_local(dtu))
739
+ assert_equal(DateTime.new(2005,6,18,17,24,23 + Rational(567,1000)), TestTimezone.new('Europe/London', period, [], dtu2).utc_to_local(dtu2))
740
+ assert_equal(Time.utc(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], t).utc_to_local(t))
741
+ assert_equal(Time.utc(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2))
742
+ assert_equal(Time.utc(2005,6,18,17,24,23,567000), TestTimezone.new('Europe/London', period, [], tu).utc_to_local(tu))
743
+ assert_equal(Time.utc(2005,6,18,17,24,23,567000), TestTimezone.new('Europe/London', period, [], tu2).utc_to_local(tu2))
744
+ assert_equal(Time.utc(2005,6,18,17,24,23).to_i, TestTimezone.new('Europe/London', period, [], ts).utc_to_local(ts))
745
+ end
746
+
747
+ def test_utc_to_local_offset
748
+ dt = DateTime.new(2005,6,18,16,24,23)
749
+ dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5,24))
750
+ dtu = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000))
751
+ dtu2 = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000)).new_offset(Rational(5,24))
752
+ t = Time.utc(2005,6,18,16,24,23)
753
+ t2 = Time.local(2005,6,18,16,24,23)
754
+ tu = Time.utc(2005,6,18,16,24,23,567000)
755
+ tu2 = Time.local(2005,6,18,16,24,23,567000)
756
+
757
+ o1 = TimezoneOffset.new(0, 0, :GMT)
758
+ o2 = TimezoneOffset.new(0, 3600, :BST)
759
+
760
+ period = TimezonePeriod.new(
761
+ TestTimezoneTransition.new(o2, o1, 1111885200),
762
+ TestTimezoneTransition.new(o1, o2, 1130634000))
763
+
764
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], dt).utc_to_local(dt).offset)
765
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], dt2).utc_to_local(dt2).offset)
766
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], dtu).utc_to_local(dtu).offset)
767
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], dtu2).utc_to_local(dtu2).offset)
768
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], t).utc_to_local(t).utc_offset)
769
+ assert(TestTimezone.new('Europe/London', period, [], t).utc_to_local(t).utc?)
770
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2).utc_offset)
771
+ assert(TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2).utc?)
772
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], tu).utc_to_local(tu).utc_offset)
773
+ assert(TestTimezone.new('Europe/London', period, [], tu).utc_to_local(tu).utc?)
774
+ assert_equal(0, TestTimezone.new('Europe/London', period, [], tu2).utc_to_local(tu2).utc_offset)
775
+ assert(TestTimezone.new('Europe/London', period, [], tu2).utc_to_local(tu2).utc?)
776
+ end
777
+
778
+ def test_local_to_utc
779
+ dt = DateTime.new(2005,6,18,16,24,23)
780
+ dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5, 24))
781
+ dtu = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000))
782
+ dtu2 = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000)).new_offset(Rational(5, 24))
783
+ t = Time.utc(2005,6,18,16,24,23)
784
+ t2 = Time.local(2005,6,18,16,24,23)
785
+ tu = Time.utc(2005,6,18,16,24,23,567000)
786
+ tu2 = Time.local(2005,6,18,16,24,23,567000)
787
+ ts = t.to_i
788
+
789
+ o1 = TimezoneOffset.new(0, 0, :GMT)
790
+ o2 = TimezoneOffset.new(0, 3600, :BST)
791
+
792
+ period = TimezonePeriod.new(
793
+ TestTimezoneTransition.new(o2, o1, 1111885200),
794
+ TestTimezoneTransition.new(o1, o2, 1130634000))
795
+
796
+ assert_equal(DateTime.new(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], dt).local_to_utc(dt))
797
+ assert_equal(DateTime.new(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], dt2).local_to_utc(dt2))
798
+ assert_equal(DateTime.new(2005,6,18,15,24,23 + Rational(567,1000)), TestTimezone.new('Europe/London', nil, [period], dtu).local_to_utc(dtu))
799
+ assert_equal(DateTime.new(2005,6,18,15,24,23 + Rational(567,1000)), TestTimezone.new('Europe/London', nil, [period], dtu2).local_to_utc(dtu2))
800
+ assert_equal(Time.utc(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t))
801
+ assert_equal(Time.utc(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2))
802
+ assert_equal(Time.utc(2005,6,18,15,24,23,567000), TestTimezone.new('Europe/London', nil, [period], tu).local_to_utc(tu))
803
+ assert_equal(Time.utc(2005,6,18,15,24,23,567000), TestTimezone.new('Europe/London', nil, [period], tu2).local_to_utc(tu2))
804
+ assert_equal(Time.utc(2005,6,18,15,24,23).to_i, TestTimezone.new('Europe/London', nil, [period], ts).local_to_utc(ts))
805
+ end
806
+
807
+ def test_local_to_utc_offset
808
+ dt = DateTime.new(2005,6,18,16,24,23)
809
+ dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5, 24))
810
+ dtu = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000))
811
+ dtu2 = DateTime.new(2005,6,18,16,24,23 + Rational(567,1000)).new_offset(Rational(5, 24))
812
+ t = Time.utc(2005,6,18,16,24,23)
813
+ t2 = Time.local(2005,6,18,16,24,23)
814
+ tu = Time.utc(2005,6,18,16,24,23,567000)
815
+ tu2 = Time.local(2005,6,18,16,24,23,567000)
816
+
817
+ o1 = TimezoneOffset.new(0, 0, :GMT)
818
+ o2 = TimezoneOffset.new(0, 3600, :BST)
819
+
820
+ period = TimezonePeriod.new(
821
+ TestTimezoneTransition.new(o2, o1, 1111885200),
822
+ TestTimezoneTransition.new(o1, o2, 1130634000))
823
+
824
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dt).local_to_utc(dt).offset)
825
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dt2).local_to_utc(dt2).offset)
826
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dtu).local_to_utc(dtu).offset)
827
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dtu2).local_to_utc(dtu2).offset)
828
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t).utc_offset)
829
+ assert(TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t).utc?)
830
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2).utc_offset)
831
+ assert(TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2).utc?)
832
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], tu).local_to_utc(tu).utc_offset)
833
+ assert(TestTimezone.new('Europe/London', nil, [period], tu).local_to_utc(tu).utc?)
834
+ assert_equal(0, TestTimezone.new('Europe/London', nil, [period], tu2).local_to_utc(tu2).utc_offset)
835
+ assert(TestTimezone.new('Europe/London', nil, [period], tu2).local_to_utc(tu2).utc?)
836
+ end
837
+
838
+ def test_local_to_utc_utc_local_returns_utc
839
+ # Check that UTC time instances are always returned even if the system
840
+ # is using UTC as the time zone.
841
+
842
+ # Note that this will only test will only work correctly on platforms where
843
+ # setting the TZ environment variable has an effect. If setting TZ has no
844
+ # effect, then this test will still pass.
845
+
846
+ old_tz = ENV['TZ']
847
+ begin
848
+ ENV['TZ'] = 'UTC'
849
+
850
+ tz = Timezone.get('America/New_York')
851
+
852
+ t = tz.local_to_utc(Time.local(2014, 1, 11, 17, 18, 41))
853
+ assert_equal(Time.utc(2014, 1, 11, 22, 18, 41), t)
854
+ assert(t.utc?)
855
+ ensure
856
+ ENV['TZ'] = old_tz
857
+ end
858
+ end
859
+
860
+ def test_local_to_utc_invalid
861
+ dt = DateTime.new(2004,4,4,2,30,0)
862
+ tz = TestTimezone.new('America/New_York', nil, [], dt)
863
+ assert_raises(PeriodNotFound) { tz.local_to_utc(dt) }
864
+
865
+ t = Time.utc(2004,4,4,2,30,0)
866
+ tz = TestTimezone.new('America/New_York', nil, [], t)
867
+ assert_raises(PeriodNotFound) { tz.local_to_utc(t) }
868
+
869
+ i = Time.utc(2004,4,4,2,30,0).to_i
870
+ tz = TestTimezone.new('America/New_York', nil, [], i)
871
+ assert_raises(PeriodNotFound) { tz.local_to_utc(i) }
872
+ end
873
+
874
+ def test_local_to_utc_ambiguous
875
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
876
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
877
+
878
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
879
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
880
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
881
+
882
+ p1 = TimezonePeriod.new(t1, t2)
883
+ p2 = TimezonePeriod.new(t2, t3)
884
+
885
+ dt = DateTime.new(2004,10,31,1,30,0)
886
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
887
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt) }
888
+
889
+ t = Time.utc(2004,10,31,1,30,0)
890
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], t)
891
+ assert_raises(AmbiguousTime) { tz.local_to_utc(t) }
892
+
893
+ i = Time.utc(2004,10,31,1,30,0).to_i
894
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], i)
895
+ assert_raises(AmbiguousTime) { tz.local_to_utc(i) }
896
+
897
+ f = Time.utc(2004,10,31,1,30,0,501).to_i
898
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], f)
899
+ assert_raises(AmbiguousTime) { tz.local_to_utc(f) }
900
+ end
901
+
902
+ def test_local_to_utc_not_found
903
+ dt = DateTime.new(2004,4,4,2,0,0)
904
+ t = Time.utc(2004,4,4,2,30,0)
905
+ i = Time.utc(2004,4,4,2,59,59).to_i
906
+
907
+ dt_tz = TestTimezone.new('America/New_York', nil, [], dt)
908
+ t_tz = TestTimezone.new('America/New_York', nil, [], t)
909
+ i_tz = TestTimezone.new('America/New_York', nil, [], i)
910
+
911
+ assert_raises(PeriodNotFound) { dt_tz.local_to_utc(dt) }
912
+ assert_raises(PeriodNotFound) { t_tz.local_to_utc(t) }
913
+ assert_raises(PeriodNotFound) { i_tz.local_to_utc(i) }
914
+ end
915
+
916
+ def test_local_to_utc_default_dst_set_true
917
+ Timezone.default_dst = true
918
+
919
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
920
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
921
+
922
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
923
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
924
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
925
+
926
+ p1 = TimezonePeriod.new(t1, t2)
927
+ p2 = TimezonePeriod.new(t2, t3)
928
+
929
+ dt = DateTime.new(2004,10,31,1,30,0)
930
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
931
+
932
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt))
933
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true))
934
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false))
935
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt, nil) }
936
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt) {|periods| raise BlockCalled, 'should not be called' })
937
+ end
938
+
939
+ def test_local_to_utc_default_dst_set_false
940
+ Timezone.default_dst = false
941
+
942
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
943
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
944
+
945
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
946
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
947
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
948
+
949
+ p1 = TimezonePeriod.new(t1, t2)
950
+ p2 = TimezonePeriod.new(t2, t3)
951
+
952
+ dt = DateTime.new(2004,10,31,1,30,0)
953
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
954
+
955
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt))
956
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false))
957
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true))
958
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt, nil) }
959
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt) {|periods| raise BlockCalled, 'should not be called' })
960
+ end
961
+
962
+ def test_local_to_utc_dst_flag_resolved
963
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
964
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
965
+
966
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
967
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
968
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
969
+
970
+ p1 = TimezonePeriod.new(t1, t2)
971
+ p2 = TimezonePeriod.new(t2, t3)
972
+
973
+ dt = DateTime.new(2004,10,31,1,30,0)
974
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
975
+
976
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true))
977
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false))
978
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true) {|periods| raise BlockCalled, 'should not be called' })
979
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false) {|periods| raise BlockCalled, 'should not be called' })
980
+ end
981
+
982
+ def test_local_to_utc_dst_block_called
983
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
984
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
985
+
986
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
987
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
988
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
989
+
990
+ p1 = TimezonePeriod.new(t1, t2)
991
+ p2 = TimezonePeriod.new(t2, t3)
992
+
993
+ dt = DateTime.new(2004,10,31,1,30,0)
994
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
995
+
996
+ assert_raises(BlockCalled) {
997
+ tz.local_to_utc(dt) {|periods|
998
+ assert_equal([p1, p2], periods)
999
+
1000
+ # raise exception to test that the block was called
1001
+ raise BlockCalled, 'should be raised'
1002
+ }
1003
+ }
1004
+
1005
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt) {|periods| periods.first})
1006
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt) {|periods| periods.last})
1007
+ assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt) {|periods| [periods.first]})
1008
+ assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt) {|periods| [periods.last]})
1009
+ end
1010
+
1011
+ def test_local_to_utc_dst_cannot_resolve
1012
+ # At midnight local time on Aug 5 1915 in Warsaw, the clocks were put back
1013
+ # 24 minutes and both periods were non-DST. Hence the block should be
1014
+ # called regardless of the value of the Boolean dst parameter.
1015
+
1016
+ o0 = TimezoneOffset.new(5040, 0, :LMT)
1017
+ o1 = TimezoneOffset.new(5040, 0, :WMT)
1018
+ o2 = TimezoneOffset.new(3600, 0, :CET)
1019
+ o3 = TimezoneOffset.new(3600, 3600, :CEST)
1020
+
1021
+ t1 = TestTimezoneTransition.new(o1, o0, DateTime.new(1879, 12, 31, 22, 36, 0))
1022
+ t2 = TestTimezoneTransition.new(o2, o1, DateTime.new(1915, 8, 4, 22, 36, 0))
1023
+ t3 = TestTimezoneTransition.new(o3, o2, DateTime.new(1916, 4, 30, 22, 0, 0))
1024
+
1025
+ p1 = TimezonePeriod.new(t1, t2)
1026
+ p2 = TimezonePeriod.new(t2, t3)
1027
+
1028
+ dt = DateTime.new(1915,8,4,23,40,0)
1029
+
1030
+ tz = TestTimezone.new('Europe/Warsaw', nil, [p1, p2], dt)
1031
+
1032
+ assert_raises(BlockCalled) do
1033
+ tz.local_to_utc(dt, true) do |periods|
1034
+ assert_equal([p1, p2], periods)
1035
+ raise BlockCalled, 'should be raised'
1036
+ end
1037
+ end
1038
+
1039
+ assert_raises(BlockCalled) do
1040
+ tz.local_to_utc(dt, false) do |periods|
1041
+ assert_equal([p1, p2], periods)
1042
+ raise BlockCalled, 'should be raised'
1043
+ end
1044
+ end
1045
+
1046
+ assert_equal(DateTime.new(1915,8,4,22,16,0), tz.local_to_utc(dt) {|periods| periods.first})
1047
+ assert_equal(DateTime.new(1915,8,4,22,40,0), tz.local_to_utc(dt) {|periods| periods.last})
1048
+ assert_equal(DateTime.new(1915,8,4,22,16,0), tz.local_to_utc(dt) {|periods| [periods.first]})
1049
+ assert_equal(DateTime.new(1915,8,4,22,40,0), tz.local_to_utc(dt) {|periods| [periods.last]})
1050
+ end
1051
+
1052
+ def test_local_to_utc_block_ambiguous
1053
+ o1 = TimezoneOffset.new(-18000, 0, :EST)
1054
+ o2 = TimezoneOffset.new(-18000, 3600, :EDT)
1055
+
1056
+ t1 = TestTimezoneTransition.new(o2, o1, 1081062000)
1057
+ t2 = TestTimezoneTransition.new(o1, o2, 1099202400)
1058
+ t3 = TestTimezoneTransition.new(o2, o1, 1112511600)
1059
+
1060
+ p1 = TimezonePeriod.new(t1, t2)
1061
+ p2 = TimezonePeriod.new(t2, t3)
1062
+
1063
+ dt = DateTime.new(2004,10,31,1,30,0)
1064
+ tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
1065
+
1066
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| nil} }
1067
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| periods} }
1068
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| []} }
1069
+ assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| raise AmbiguousTime, 'Ambiguous time'} }
1070
+ end
1071
+
1072
+ def test_offsets_up_to
1073
+ o1 = TimezoneOffset.new(-17900, 0, :TESTLMT)
1074
+ o2 = TimezoneOffset.new(-18000, 3600, :TESTD)
1075
+ o3 = TimezoneOffset.new(-18000, 0, :TESTS)
1076
+ o4 = TimezoneOffset.new(-21600, 3600, :TESTD)
1077
+ o5 = TimezoneOffset.new(-21600, 0, :TESTS)
1078
+
1079
+ t1 = TestTimezoneTransition.new(o2, o1, Time.utc(2010, 4,1,1,0,0).to_i)
1080
+ t2 = TestTimezoneTransition.new(o3, o2, Time.utc(2010,10,1,1,0,0).to_i)
1081
+ t3 = TestTimezoneTransition.new(o2, o3, Time.utc(2011, 3,1,1,0,0).to_i)
1082
+ t4 = TestTimezoneTransition.new(o4, o2, Time.utc(2011, 4,1,1,0,0).to_i)
1083
+ t5 = TestTimezoneTransition.new(o3, o4, Time.utc(2011,10,1,1,0,0).to_i)
1084
+ t6 = TestTimezoneTransition.new(o5, o3, Time.utc(2012, 3,1,1,0,0).to_i)
1085
+
1086
+ assert_array_same_items([o1, o2, o3, o4, o5],
1087
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1), nil, [t1, t2, t3, t4, t5, t6]).
1088
+ offsets_up_to(Time.utc(2012,3,1,1,0,1)))
1089
+ assert_array_same_items([o2, o3, o4, o5],
1090
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1), Time.utc(2010,4,1,1,0,0), [t1, t2, t3, t4, t5, t6]).
1091
+ offsets_up_to(Time.utc(2012,3,1,1,0,1), Time.utc(2010,4,1,1,0,0)))
1092
+ assert_array_same_items([o1, o2, o3, o4],
1093
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,0), nil, [t1, t2, t3, t4, t5]).
1094
+ offsets_up_to(Time.utc(2012,3,1,1,0,0)))
1095
+ assert_array_same_items([o2, o3, o4, o5],
1096
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1), Time.utc(2010,4,1,1,0,1), [t2, t3, t4, t5, t6]).
1097
+ offsets_up_to(Time.utc(2012,3,1,1,0,1), Time.utc(2010,4,1,1,0,1)))
1098
+ assert_array_same_items([o2, o3],
1099
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2011,3,1,2,0,0), Time.utc(2011,3,1,0,0,0), [t3]).
1100
+ offsets_up_to(Time.utc(2011,3,1,2,0,0), Time.utc(2011,3,1,0,0,0)))
1101
+ assert_array_same_items([o3, o4],
1102
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,0), Time.utc(2011,4,1,1,0,0), [t4, t5]).
1103
+ offsets_up_to(Time.utc(2012,3,1,1,0,0), Time.utc(2011,4,1,1,0,0)))
1104
+
1105
+ assert_array_same_items([o1, o2, o3, o4, o5],
1106
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1).to_i, nil, [t1, t2, t3, t4, t5, t6]).
1107
+ offsets_up_to(Time.utc(2012,3,1,1,0,1).to_i))
1108
+ assert_array_same_items([o2, o3, o4, o5],
1109
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,0).to_i, [t1, t2, t3, t4, t5, t6]).
1110
+ offsets_up_to(Time.utc(2012,3,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,0).to_i))
1111
+ assert_array_same_items([o1, o2, o3, o4],
1112
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,0).to_i, nil, [t1, t2, t3, t4, t5]).
1113
+ offsets_up_to(Time.utc(2012,3,1,1,0,0).to_i))
1114
+ assert_array_same_items([o2, o3, o4, o5],
1115
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,1).to_i, [t2, t3, t4, t5, t6]).
1116
+ offsets_up_to(Time.utc(2012,3,1,1,0,1).to_i, Time.utc(2010,4,1,1,0,1).to_i))
1117
+ assert_array_same_items([o2, o3],
1118
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2011,3,1,2,0,0).to_i, Time.utc(2011,3,1,0,0,0).to_i, [t3]).
1119
+ offsets_up_to(Time.utc(2011,3,1,2,0,0).to_i, Time.utc(2011,3,1,0,0,0).to_i))
1120
+ assert_array_same_items([o3, o4],
1121
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,3,1,1,0,0).to_i, Time.utc(2011,4,1,1,0,0).to_i, [t4, t5]).
1122
+ offsets_up_to(Time.utc(2012,3,1,1,0,0).to_i, Time.utc(2011,4,1,1,0,0).to_i))
1123
+
1124
+ assert_array_same_items([o1, o2, o3, o4, o5],
1125
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,3,1,1,0,1), nil, [t1, t2, t3, t4, t5, t6]).
1126
+ offsets_up_to(DateTime.new(2012,3,1,1,0,1)))
1127
+ assert_array_same_items([o2, o3, o4, o5],
1128
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,3,1,1,0,1), DateTime.new(2010,4,1,1,0,0), [t1, t2, t3, t4, t5, t6]).
1129
+ offsets_up_to(DateTime.new(2012,3,1,1,0,1), DateTime.new(2010,4,1,1,0,0)))
1130
+ assert_array_same_items([o1, o2, o3, o4],
1131
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,3,1,1,0,0), nil, [t1, t2, t3, t4, t5]).
1132
+ offsets_up_to(DateTime.new(2012,3,1,1,0,0)))
1133
+ assert_array_same_items([o2, o3, o4, o5],
1134
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,3,1,1,0,1), DateTime.new(2010,4,1,1,0,1), [t2, t3, t4, t5, t6]).
1135
+ offsets_up_to(DateTime.new(2012,3,1,1,0,1), DateTime.new(2010,4,1,1,0,1)))
1136
+ assert_array_same_items([o2, o3],
1137
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2011,3,1,2,0,0), DateTime.new(2011,3,1,0,0,0), [t3]).
1138
+ offsets_up_to(DateTime.new(2011,3,1,2,0,0), DateTime.new(2011,3,1,0,0,0)))
1139
+ assert_array_same_items([o3, o4],
1140
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,3,1,1,0,0), DateTime.new(2011,4,1,1,0,0), [t4, t5]).
1141
+ offsets_up_to(DateTime.new(2012,3,1,1,0,0), DateTime.new(2011,4,1,1,0,0)))
1142
+ end
1143
+
1144
+ def test_offsets_up_to_no_transitions
1145
+ o = TimezoneOffset.new(600, 0, :LMT)
1146
+ p = TimezonePeriod.new(nil, nil, o)
1147
+
1148
+ assert_array_same_items([o],
1149
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', Time.utc(2000,1,1,1,0,0), nil, p).
1150
+ offsets_up_to(Time.utc(2000,1,1,1,0,0)))
1151
+ assert_array_same_items([o],
1152
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', Time.utc(2000,1,1,1,0,0), Time.utc(1990,1,1,1,0,0), p).
1153
+ offsets_up_to(Time.utc(2000,1,1,1,0,0), Time.utc(1990,1,1,1,0,0)))
1154
+
1155
+ assert_array_same_items([o],
1156
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', Time.utc(2000,1,1,1,0,0).to_i, nil, p).
1157
+ offsets_up_to(Time.utc(2000,1,1,1,0,0).to_i))
1158
+ assert_array_same_items([o],
1159
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', Time.utc(2000,1,1,1,0,0).to_i, Time.utc(1990,1,1,1,0,0).to_i, p).
1160
+ offsets_up_to(Time.utc(2000,1,1,1,0,0).to_i, Time.utc(1990,1,1,1,0,0).to_i))
1161
+
1162
+ assert_array_same_items([o],
1163
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', DateTime.new(2000,1,1,1,0,0), nil, p).
1164
+ offsets_up_to(DateTime.new(2000,1,1,1,0,0)))
1165
+ assert_array_same_items([o],
1166
+ OffsetsUpToNoTransitionsTestTimezone.new('Test/Zone', DateTime.new(2000,1,1,1,0,0), DateTime.new(1990,1,1,1,0,0), p).
1167
+ offsets_up_to(DateTime.new(2000,1,1,1,0,0), DateTime.new(1990,1,1,1,0,0)))
1168
+ end
1169
+
1170
+ def test_offsets_up_to_utc_to_not_greater_than_utc_from
1171
+ assert_raises(ArgumentError) do
1172
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,8,1,0,0,0), Time.utc(2012,8,1,0,0,0), []).
1173
+ offsets_up_to(Time.utc(2012,8,1,0,0,0), Time.utc(2012,8,1,0,0,0))
1174
+ end
1175
+
1176
+ assert_raises(ArgumentError) do
1177
+ OffsetsUpToTestTimezone.new('Test/Zone', Time.utc(2012,8,1,0,0,0).to_i, Time.utc(2012,8,1,0,0,0).to_i, []).
1178
+ offsets_up_to(Time.utc(2012,8,1,0,0,0).to_i, Time.utc(2012,8,1,0,0,0).to_i)
1179
+ end
1180
+
1181
+ assert_raises(ArgumentError) do
1182
+ OffsetsUpToTestTimezone.new('Test/Zone', DateTime.new(2012,8,1,0,0,0), DateTime.new(2012,8,1,0,0,0), []).
1183
+ offsets_up_to(DateTime.new(2012,8,1,0,0,0), DateTime.new(2012,8,1,0,0,0))
1184
+ end
1185
+ end
1186
+
1187
+ def test_now
1188
+ assert_kind_of(Time, Timezone.get('Europe/London').now)
1189
+ end
1190
+
1191
+ def test_current_period
1192
+ assert_kind_of(TimezonePeriod, Timezone.get('Europe/London').current_period)
1193
+ end
1194
+
1195
+ def test_current_period_and_time
1196
+ current = Timezone.get('Europe/London').current_period_and_time
1197
+ assert_equal(2, current.length)
1198
+ assert_kind_of(Time, current[0])
1199
+ assert_kind_of(TimezonePeriod, current[1])
1200
+ end
1201
+
1202
+ def test_current_time_and_period
1203
+ current = Timezone.get('Europe/London').current_time_and_period
1204
+ assert_equal(2, current.length)
1205
+ assert_kind_of(Time, current[0])
1206
+ assert_kind_of(TimezonePeriod, current[1])
1207
+ end
1208
+
1209
+ def test_compare
1210
+ assert_equal(0, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/London'))
1211
+ assert_equal(-1, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/london'))
1212
+ assert_equal(-1, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/Paris'))
1213
+ assert_equal(1, TestTimezone.new('Europe/Paris') <=> TestTimezone.new('Europe/London'))
1214
+ assert_equal(-1, TestTimezone.new('America/New_York') <=> TestTimezone.new('Europe/Paris'))
1215
+ assert_equal(1, TestTimezone.new('Europe/Paris') <=> TestTimezone.new('America/New_York'))
1216
+ end
1217
+
1218
+ def test_compare_non_comparable
1219
+ assert_nil(TestTimezone.new('Europe/London') <=> Object.new)
1220
+ end
1221
+
1222
+ def test_equality
1223
+ assert_equal(true, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/London'))
1224
+ assert_equal(false, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/london'))
1225
+ assert_equal(false, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/Paris'))
1226
+ assert(!(TestTimezone.new('Europe/London') == Object.new))
1227
+ end
1228
+
1229
+ def test_eql
1230
+ assert_equal(true, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/London')))
1231
+ assert_equal(false, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/london')))
1232
+ assert_equal(false, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/Paris')))
1233
+ assert(!TestTimezone.new('Europe/London').eql?(Object.new))
1234
+ end
1235
+
1236
+ def test_hash
1237
+ assert_equal('Europe/London'.hash, TestTimezone.new('Europe/London').hash)
1238
+ assert_equal('America/New_York'.hash, TestTimezone.new('America/New_York').hash)
1239
+ end
1240
+
1241
+ def test_marshal_data
1242
+ tz = Timezone.get('Europe/London')
1243
+ assert_kind_of(DataTimezone, tz)
1244
+ assert_same(tz, Marshal.load(Marshal.dump(tz)))
1245
+ end
1246
+
1247
+ def test_marshal_linked
1248
+ tz = Timezone.get('UTC')
1249
+
1250
+ # ZoneinfoDataSource doesn't return LinkedTimezoneInfo for any timezone.
1251
+ if DataSource.get.load_timezone_info('UTC').kind_of?(LinkedTimezoneInfo)
1252
+ assert_kind_of(LinkedTimezone, tz)
1253
+ else
1254
+ assert_kind_of(DataTimezone, tz)
1255
+ end
1256
+
1257
+ assert_same(tz, Marshal.load(Marshal.dump(tz)))
1258
+ end
1259
+
1260
+ def test_strftime_datetime
1261
+ tz = Timezone.get('Europe/London')
1262
+ dt = DateTime.new(2006, 7, 15, 22, 12, 2)
1263
+ assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', dt))
1264
+ assert_equal('BST', tz.strftime('%Z', dt))
1265
+ assert_equal('%ZBST', tz.strftime('%%Z%Z', dt))
1266
+ assert_equal('BST BST', tz.strftime('%Z %Z', dt))
1267
+ assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', dt))
1268
+ assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', dt))
1269
+ assert_equal('1153001522 %s %1153001522', tz.strftime('%s %%s %%%s', dt))
1270
+ end
1271
+
1272
+ def test_strftime_time
1273
+ tz = Timezone.get('Europe/London')
1274
+ t = Time.utc(2006, 7, 15, 22, 12, 2)
1275
+ assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', t))
1276
+ assert_equal('BST', tz.strftime('%Z', t))
1277
+ assert_equal('%ZBST', tz.strftime('%%Z%Z', t))
1278
+ assert_equal('BST BST', tz.strftime('%Z %Z', t))
1279
+ assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', t))
1280
+ assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', t))
1281
+ assert_equal('1153001522 %s %1153001522', tz.strftime('%s %%s %%%s', t))
1282
+ end
1283
+
1284
+ def test_strftime_int
1285
+ tz = Timezone.get('Europe/London')
1286
+ i = Time.utc(2006, 7, 15, 22, 12, 2).to_i
1287
+ assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', i))
1288
+ assert_equal('BST', tz.strftime('%Z', i))
1289
+ assert_equal('%ZBST', tz.strftime('%%Z%Z', i))
1290
+ assert_equal('BST BST', tz.strftime('%Z %Z', i))
1291
+ assert_equal('BST %Z %BST %%Z %%BST', tz.strftime('%Z %%Z %%%Z %%%%Z %%%%%Z', i))
1292
+ assert_equal('+0100 +01:00 +01:00:00 +01 %::::z', tz.strftime('%z %:z %::z %:::z %::::z', i))
1293
+ assert_equal('1153001522 %s %1153001522', tz.strftime('%s %%s %%%s', i))
1294
+ end
1295
+
1296
+ def test_get_missing_data_source
1297
+ DataSource.set(DataSource.new)
1298
+
1299
+ assert_raises(InvalidDataSource) do
1300
+ Timezone.get('Europe/London')
1301
+ end
1302
+ end
1303
+
1304
+ def test_new_missing_data_source
1305
+ DataSource.set(DataSource.new)
1306
+
1307
+ assert_raises(InvalidDataSource) do
1308
+ Timezone.new('Europe/London')
1309
+ end
1310
+ end
1311
+
1312
+ def test_all_missing_data_source
1313
+ DataSource.set(DataSource.new)
1314
+
1315
+ assert_raises(InvalidDataSource) do
1316
+ Timezone.all
1317
+ end
1318
+ end
1319
+
1320
+ def test_all_identifiers_missing_data_source
1321
+ DataSource.set(DataSource.new)
1322
+
1323
+ assert_raises(InvalidDataSource) do
1324
+ Timezone.all_identifiers
1325
+ end
1326
+ end
1327
+
1328
+ def test_all_data_zones_missing_data_source
1329
+ DataSource.set(DataSource.new)
1330
+
1331
+ assert_raises(InvalidDataSource) do
1332
+ Timezone.all_data_zones
1333
+ end
1334
+ end
1335
+
1336
+ def test_all_data_zone_identifiers_missing_data_source
1337
+ DataSource.set(DataSource.new)
1338
+
1339
+ assert_raises(InvalidDataSource) do
1340
+ Timezone.all_data_zone_identifiers
1341
+ end
1342
+ end
1343
+
1344
+ def test_all_linked_zones_missing_data_source
1345
+ DataSource.set(DataSource.new)
1346
+
1347
+ assert_raises(InvalidDataSource) do
1348
+ Timezone.all_linked_zones
1349
+ end
1350
+ end
1351
+
1352
+ def test_all_linked_zone_identifiers_missing_data_source
1353
+ DataSource.set(DataSource.new)
1354
+
1355
+ assert_raises(InvalidDataSource) do
1356
+ Timezone.all_linked_zone_identifiers
1357
+ end
1358
+ end
1359
+ end