PageRenderTime 33ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/External.LCA_RESTRICTED/Languages/Ruby/ruby19/lib/ruby/gems/1.9.1/gems/tzinfo-0.3.23/test/tc_timezone.rb

http://github.com/IronLanguages/main
Ruby | 849 lines | 654 code | 176 blank | 19 comment | 6 complexity | 5a66b7ddb5a514c367a5ff95e8c58009 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
  2. require 'test/unit'
  3. require File.join(File.dirname(__FILE__), 'test_utils')
  4. require 'tzinfo'
  5. include TZInfo
  6. class TCTimezone < Test::Unit::TestCase
  7. class BlockCalled < StandardError
  8. end
  9. class TestTimezone < Timezone
  10. def self.new(identifier, period_for_utc = nil, periods_for_local = nil, expected = nil)
  11. t = super()
  12. t.send(:setup, identifier, period_for_utc, periods_for_local, expected)
  13. t
  14. end
  15. def identifier
  16. @identifier
  17. end
  18. def period_for_utc(utc)
  19. utc = TimeOrDateTime.wrap(utc)
  20. raise "Unexpected utc #{utc} in period_for_utc" unless @expected.eql?(utc)
  21. @period_for_utc
  22. end
  23. def periods_for_local(local)
  24. local = TimeOrDateTime.wrap(local)
  25. raise "Unexpected local #{local} in periods_for_local" unless @expected.eql?(local)
  26. @periods_for_local.clone
  27. end
  28. private
  29. def setup(identifier, period_for_utc, periods_for_local, expected)
  30. @identifier = identifier
  31. @period_for_utc = period_for_utc
  32. @periods_for_local = periods_for_local || []
  33. @expected = TimeOrDateTime.wrap(expected)
  34. end
  35. end
  36. def test_get_valid_1
  37. tz = Timezone.get('Europe/London')
  38. assert_kind_of(DataTimezone, tz)
  39. assert_equal('Europe/London', tz.identifier)
  40. end
  41. def test_get_valid_2
  42. tz = Timezone.get('UTC')
  43. assert_kind_of(LinkedTimezone, tz)
  44. assert_equal('UTC', tz.identifier)
  45. end
  46. def test_get_valid_3
  47. tz = Timezone.get('America/Argentina/Buenos_Aires')
  48. assert_kind_of(DataTimezone, tz)
  49. assert_equal('America/Argentina/Buenos_Aires', tz.identifier)
  50. end
  51. def test_get_same_instance
  52. tz1 = Timezone.get('Europe/London')
  53. tz2 = Timezone.get('Europe/London')
  54. assert_same(tz1, tz2)
  55. end
  56. def test_get_not_exist
  57. assert_raises(InvalidTimezoneIdentifier) { Timezone.get('Nowhere/Special') }
  58. end
  59. def test_get_invalid
  60. assert_raises(InvalidTimezoneIdentifier) { Timezone.get('../Definitions/UTC') }
  61. end
  62. def test_get_nil
  63. assert_raises(InvalidTimezoneIdentifier) { Timezone.get(nil) }
  64. end
  65. def test_get_plus
  66. tz = Timezone.get('Etc/GMT+1')
  67. assert_equal('Etc/GMT+1', tz.identifier)
  68. end
  69. def test_get_minus
  70. tz = Timezone.get('Etc/GMT-1')
  71. assert_equal('Etc/GMT-1', tz.identifier)
  72. end
  73. def test_get_case
  74. Timezone.get('Europe/Prague')
  75. assert_raises(InvalidTimezoneIdentifier) { Timezone.get('Europe/prague') }
  76. end
  77. def test_get_proxy_valid
  78. proxy = Timezone.get_proxy('Europe/London')
  79. assert_kind_of(TimezoneProxy, proxy)
  80. assert_equal('Europe/London', proxy.identifier)
  81. end
  82. def test_get_proxy_not_exist
  83. proxy = Timezone.get_proxy('Not/There')
  84. assert_kind_of(TimezoneProxy, proxy)
  85. assert_equal('Not/There', proxy.identifier)
  86. end
  87. def test_get_proxy_invalid
  88. proxy = Timezone.get_proxy('../Invalid/Identifier')
  89. assert_kind_of(TimezoneProxy, proxy)
  90. assert_equal('../Invalid/Identifier', proxy.identifier)
  91. end
  92. def test_get_tainted_loaded
  93. Timezone.get('Europe/Andorra')
  94. safe_test do
  95. tz = Timezone.get('Europe/Andorra'.taint)
  96. assert_equal('Europe/Andorra', tz.identifier)
  97. end
  98. end
  99. # Disable test in Ruby 1.9. See:
  100. # http://groups.google.com/group/ruby-talk-google/browse_thread/thread/170a7205555cedfc
  101. # It doesn't appear to be possible to require a file from the load path in Ruby 1.9.
  102. if RUBY_VERSION !~ /^1.9/
  103. def test_get_tainted_not_loaded
  104. safe_test do
  105. tz = Timezone.get('Europe/Amsterdam'.taint)
  106. assert_equal('Europe/Amsterdam', tz.identifier)
  107. end
  108. end
  109. end
  110. def test_new_no_args
  111. tz = Timezone.new
  112. assert_raises(UnknownTimezone) { tz.identifier }
  113. assert_raises(UnknownTimezone) { tz.friendly_identifier }
  114. assert_raises(UnknownTimezone) { tz.utc_to_local(DateTime.new(2006,1,1,1,0,0)) }
  115. assert_raises(UnknownTimezone) { tz.local_to_utc(DateTime.new(2006,1,1,1,0,0)) }
  116. assert_raises(UnknownTimezone) { tz.period_for_utc(DateTime.new(2006,1,1,1,0,0)) }
  117. assert_raises(UnknownTimezone) { tz.periods_for_local(DateTime.new(2006,1,1,1,0,0)) }
  118. assert_raises(UnknownTimezone) { tz.period_for_local(DateTime.new(2006,1,1,1,0,0)) }
  119. assert_raises(UnknownTimezone) { tz.now }
  120. assert_raises(UnknownTimezone) { tz.current_period_and_time }
  121. end
  122. def test_new_nil
  123. tz = Timezone.new(nil)
  124. assert_raises(UnknownTimezone) { tz.identifier }
  125. assert_raises(UnknownTimezone) { tz.friendly_identifier }
  126. assert_raises(UnknownTimezone) { tz.utc_to_local(DateTime.new(2006,1,1,1,0,0)) }
  127. assert_raises(UnknownTimezone) { tz.local_to_utc(DateTime.new(2006,1,1,1,0,0)) }
  128. assert_raises(UnknownTimezone) { tz.period_for_utc(DateTime.new(2006,1,1,1,0,0)) }
  129. assert_raises(UnknownTimezone) { tz.periods_for_local(DateTime.new(2006,1,1,1,0,0)) }
  130. assert_raises(UnknownTimezone) { tz.period_for_local(DateTime.new(2006,1,1,1,0,0)) }
  131. assert_raises(UnknownTimezone) { tz.now }
  132. assert_raises(UnknownTimezone) { tz.current_period_and_time }
  133. end
  134. def test_new_arg
  135. tz = Timezone.new('Europe/London')
  136. assert_same(Timezone.get('Europe/London'), tz)
  137. end
  138. def test_new_arg_not_exist
  139. assert_raises(InvalidTimezoneIdentifier) { Timezone.new('Nowhere/Special') }
  140. end
  141. def test_all
  142. all = Timezone.all
  143. expected = Indexes::Timezones.timezones.collect {|identifier| Timezone.get_proxy(identifier)}
  144. assert_equal(expected, all)
  145. end
  146. def test_all_identifiers
  147. all = Timezone.all_identifiers
  148. assert_equal(Indexes::Timezones.timezones, all)
  149. end
  150. def test_all_data_zones
  151. all_data = Timezone.all_data_zones
  152. expected = Indexes::Timezones.data_timezones.collect {|identifier| Timezone.get_proxy(identifier)}
  153. assert_equal(expected, all_data)
  154. end
  155. def test_all_data_zone_identifiers
  156. all_data = Timezone.all_data_zone_identifiers
  157. assert_equal(Indexes::Timezones.data_timezones, all_data)
  158. end
  159. def test_all_linked_zones
  160. all_linked = Timezone.all_linked_zones
  161. expected = Indexes::Timezones.linked_timezones.collect {|identifier| Timezone.get_proxy(identifier)}
  162. assert_equal(expected, all_linked)
  163. end
  164. def test_all_linked_zone_identifiers
  165. all_linked = Timezone.all_linked_zone_identifiers
  166. assert_equal(Indexes::Timezones.linked_timezones, all_linked)
  167. end
  168. def test_all_country_zones
  169. # Probably should relax this test - just need all the zones, don't care
  170. # about order.
  171. expected = Country.all.inject([]) {|result,country|
  172. result += country.zones
  173. }
  174. expected.uniq!
  175. all_country_zones = Timezone.all_country_zones
  176. assert_equal(expected, all_country_zones)
  177. all_country_zone_identifiers = Timezone.all_country_zone_identifiers
  178. assert_equal(all_country_zone_identifiers.length, all_country_zones.length)
  179. all_country_zones.each {|zone|
  180. assert_kind_of(TimezoneProxy, zone)
  181. assert(all_country_zone_identifiers.include?(zone.identifier))
  182. }
  183. end
  184. def test_all_country_zone_identifiers
  185. # Probably should relax this test - just need all the zones, don't care
  186. # about order.
  187. expected = Country.all.inject([]) {|result,country|
  188. result += country.zone_identifiers
  189. }
  190. expected.uniq!
  191. assert_equal(expected, Timezone.all_country_zone_identifiers)
  192. end
  193. def test_us_zones
  194. # Probably should relax this test - just need all the zones, don't care
  195. # about order.
  196. us_zones = Timezone.us_zones
  197. assert_equal(Country.get('US').zones.uniq, us_zones)
  198. us_zone_identifiers = Timezone.us_zone_identifiers
  199. assert_equal(us_zone_identifiers.length, us_zones.length)
  200. us_zones.each {|zone|
  201. assert_kind_of(TimezoneProxy, zone)
  202. assert(us_zone_identifiers.include?(zone.identifier))
  203. }
  204. end
  205. def test_us_zone_identifiers
  206. # Probably should relax this test - just need all the zones, don't care
  207. # about order.
  208. assert_equal(Country.get('US').zone_identifiers.uniq, Timezone.us_zone_identifiers)
  209. end
  210. def test_identifier
  211. assert_raises(UnknownTimezone) { Timezone.new.identifier }
  212. assert_equal('Europe/Paris', TestTimezone.new('Europe/Paris').identifier)
  213. end
  214. def test_name
  215. assert_raises(UnknownTimezone) { Timezone.new.name }
  216. assert_equal('Europe/Paris', TestTimezone.new('Europe/Paris').name)
  217. end
  218. def test_friendly_identifier
  219. assert_equal('Paris', TestTimezone.new('Europe/Paris').friendly_identifier(true))
  220. assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').friendly_identifier(false))
  221. assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').friendly_identifier)
  222. assert_equal('Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier(true))
  223. assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier(false))
  224. assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').friendly_identifier)
  225. assert_equal('Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier(true))
  226. assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier(false))
  227. assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').friendly_identifier)
  228. assert_equal('McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier(true))
  229. assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier(false))
  230. assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').friendly_identifier)
  231. assert_equal('GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier(true))
  232. assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier(false))
  233. assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').friendly_identifier)
  234. assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier(true))
  235. assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier(false))
  236. assert_equal('UTC', TestTimezone.new('UTC').friendly_identifier)
  237. end
  238. def test_to_s
  239. assert_equal('Europe - Paris', TestTimezone.new('Europe/Paris').to_s)
  240. assert_equal('America - Knox, Indiana', TestTimezone.new('America/Indiana/Knox').to_s)
  241. assert_equal('Antarctica - Dumont D\'Urville', TestTimezone.new('Antarctica/DumontDUrville').to_s)
  242. assert_equal('Antarctica - McMurdo', TestTimezone.new('Antarctica/McMurdo').to_s)
  243. assert_equal('Etc - GMT+1', TestTimezone.new('Etc/GMT+1').to_s)
  244. assert_equal('UTC', TestTimezone.new('UTC').to_s)
  245. end
  246. def test_period_for_local
  247. dt = DateTime.new(2005,2,18,16,24,23)
  248. dt2 = DateTime.new(2005,2,18,16,24,23).new_offset(Rational(5,24))
  249. t = Time.utc(2005,2,18,16,24,23)
  250. t2 = Time.local(2005,2,18,16,24,23)
  251. ts = t.to_i
  252. o1 = TimezoneOffsetInfo.new(0, 0, :GMT)
  253. o2 = TimezoneOffsetInfo.new(0, 3600, :BST)
  254. period = TimezonePeriod.new(
  255. TimezoneTransitionInfo.new(o1, o2, 1099184400),
  256. TimezoneTransitionInfo.new(o2, o1, 1111885200))
  257. dt_period = TestTimezone.new('Europe/London', nil, [period], dt).period_for_local(dt)
  258. dt2_period = TestTimezone.new('Europe/London', nil, [period], dt2).period_for_local(dt2)
  259. t_period = TestTimezone.new('Europe/London', nil, [period], t).period_for_local(t)
  260. t2_period = TestTimezone.new('Europe/London', nil, [period], t2).period_for_local(t2)
  261. ts_period = TestTimezone.new('Europe/London', nil, [period], ts).period_for_local(ts)
  262. assert_equal(period, dt_period)
  263. assert_equal(period, dt2_period)
  264. assert_equal(period, t_period)
  265. assert_equal(period, t2_period)
  266. assert_equal(period, ts_period)
  267. end
  268. def test_period_for_local_invalid
  269. dt = DateTime.new(2004,4,4,2,30,0)
  270. tz = TestTimezone.new('America/New_York', nil, [], dt)
  271. assert_raises(PeriodNotFound) do
  272. tz.period_for_local(dt)
  273. end
  274. end
  275. def test_period_for_local_ambiguous
  276. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  277. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  278. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  279. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  280. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  281. p1 = TimezonePeriod.new(t1, t2)
  282. p2 = TimezonePeriod.new(t2, t3)
  283. dt = DateTime.new(2004,10,31,1, 0,0)
  284. t = Time.utc(2004,10,31,1,30,0)
  285. i = Time.utc(2004,10,31,1,59,59).to_i
  286. dt_tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  287. t_tz = TestTimezone.new('America/New_York', nil, [p1, p2], t)
  288. i_tz = TestTimezone.new('America/New_York', nil, [p1, p2], i)
  289. assert_raises(AmbiguousTime) { dt_tz.period_for_local(dt) }
  290. assert_raises(AmbiguousTime) { t_tz.period_for_local(t) }
  291. assert_raises(AmbiguousTime) { i_tz.period_for_local(i) }
  292. end
  293. def test_period_for_local_not_found
  294. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  295. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  296. t1 = TimezoneTransitionInfo.new(o1, o2, 1067148000)
  297. t2 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  298. t3 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  299. p1 = TimezonePeriod.new(t1, t2)
  300. p2 = TimezonePeriod.new(t2, t3)
  301. dt = DateTime.new(2004,4,4,2,0,0)
  302. t = Time.utc(2004,4,4,2,30,0)
  303. i = Time.utc(2004,4,4,2,59,59).to_i
  304. dt_tz = TestTimezone.new('America/New_York', nil, [], dt)
  305. t_tz = TestTimezone.new('America/New_York', nil, [], t)
  306. i_tz = TestTimezone.new('America/New_York', nil, [], i)
  307. assert_raises(PeriodNotFound) { dt_tz.period_for_local(dt) }
  308. assert_raises(PeriodNotFound) { t_tz.period_for_local(t) }
  309. assert_raises(PeriodNotFound) { i_tz.period_for_local(i) }
  310. end
  311. def test_period_for_local_dst_flag_resolved
  312. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  313. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  314. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  315. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  316. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  317. p1 = TimezonePeriod.new(t1, t2)
  318. p2 = TimezonePeriod.new(t2, t3)
  319. dt = DateTime.new(2004,10,31,1,30,0)
  320. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  321. assert_equal(p1, tz.period_for_local(dt, true))
  322. assert_equal(p2, tz.period_for_local(dt, false))
  323. assert_equal(p1, tz.period_for_local(dt, true) {|periods| raise BlockCalled, 'should not be called' })
  324. assert_equal(p2, tz.period_for_local(dt, false) {|periods| raise BlockCalled, 'should not be called' })
  325. end
  326. def test_period_for_local_dst_block_called
  327. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  328. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  329. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  330. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  331. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  332. p1 = TimezonePeriod.new(t1, t2)
  333. p2 = TimezonePeriod.new(t2, t3)
  334. dt = DateTime.new(2004,10,31,1,30,0)
  335. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  336. assert_raises(BlockCalled) {
  337. tz.period_for_local(dt) {|periods|
  338. assert_equal([p1, p2], periods)
  339. # raise exception to test that the block was called
  340. raise BlockCalled, 'should be raised'
  341. }
  342. }
  343. assert_equal(p1, tz.period_for_local(dt) {|periods| periods.first})
  344. assert_equal(p2, tz.period_for_local(dt) {|periods| periods.last})
  345. assert_equal(p1, tz.period_for_local(dt) {|periods| [periods.first]})
  346. assert_equal(p2, tz.period_for_local(dt) {|periods| [periods.last]})
  347. end
  348. def test_period_for_local_dst_cannot_resolve
  349. # At midnight local time on Aug 5 1915 in Warsaw, the clocks were put back
  350. # 24 minutes and both periods were non-DST. Hence the block should be
  351. # called regardless of the value of the Boolean dst parameter.
  352. o0 = TimezoneOffsetInfo.new(5040, 0, :LMT)
  353. o1 = TimezoneOffsetInfo.new(5040, 0, :WMT)
  354. o2 = TimezoneOffsetInfo.new(3600, 0, :CET)
  355. o3 = TimezoneOffsetInfo.new(3600, 3600, :CEST)
  356. t1 = TimezoneTransitionInfo.new(o1, o0, 288925853, 120)
  357. t2 = TimezoneTransitionInfo.new(o2, o1, 290485733, 120)
  358. t3 = TimezoneTransitionInfo.new(o3, o2, 29051813, 12)
  359. p1 = TimezonePeriod.new(t1, t2)
  360. p2 = TimezonePeriod.new(t2, t3)
  361. dt = DateTime.new(1915,8,4,23,40,0)
  362. tz = TestTimezone.new('Europe/Warsaw', nil, [p1, p2], dt)
  363. assert_raises(BlockCalled) {
  364. tz.period_for_local(dt, true) {|periods|
  365. assert_equal([p1, p2], periods)
  366. raise BlockCalled, 'should be raised'
  367. }
  368. }
  369. assert_raises(BlockCalled) {
  370. tz.period_for_local(dt, false) {|periods|
  371. assert_equal([p1, p2], periods)
  372. raise BlockCalled, 'should be raised'
  373. }
  374. }
  375. end
  376. def test_period_for_local_block_ambiguous
  377. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  378. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  379. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  380. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  381. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  382. p1 = TimezonePeriod.new(t1, t2)
  383. p2 = TimezonePeriod.new(t2, t3)
  384. dt = DateTime.new(2004,10,31,1,30,0)
  385. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  386. assert_raises(AmbiguousTime) do
  387. tz.period_for_local(dt) {|periods| nil}
  388. end
  389. assert_raises(AmbiguousTime) do
  390. tz.period_for_local(dt) {|periods| periods}
  391. end
  392. assert_raises(AmbiguousTime) do
  393. tz.period_for_local(dt) {|periods| []}
  394. end
  395. assert_raises(AmbiguousTime) do
  396. tz.period_for_local(dt) {|periods| raise AmbiguousTime, 'Ambiguous time'}
  397. end
  398. end
  399. def test_utc_to_local
  400. dt = DateTime.new(2005,6,18,16,24,23)
  401. dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5,24))
  402. t = Time.utc(2005,6,18,16,24,23)
  403. t2 = Time.local(2005,6,18,16,24,23)
  404. ts = t.to_i
  405. o1 = TimezoneOffsetInfo.new(0, 0, :GMT)
  406. o2 = TimezoneOffsetInfo.new(0, 3600, :BST)
  407. period = TimezonePeriod.new(
  408. TimezoneTransitionInfo.new(o2, o1, 1111885200),
  409. TimezoneTransitionInfo.new(o1, o2, 1130634000))
  410. assert_equal(DateTime.new(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], dt).utc_to_local(dt))
  411. assert_equal(DateTime.new(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], dt2).utc_to_local(dt2))
  412. assert_equal(Time.utc(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], t).utc_to_local(t))
  413. assert_equal(Time.utc(2005,6,18,17,24,23), TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2))
  414. assert_equal(Time.utc(2005,6,18,17,24,23).to_i, TestTimezone.new('Europe/London', period, [], ts).utc_to_local(ts))
  415. end
  416. def test_utc_to_local_offset
  417. dt = DateTime.new(2005,6,18,16,24,23)
  418. dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5,24))
  419. t = Time.utc(2005,6,18,16,24,23)
  420. t2 = Time.local(2005,6,18,16,24,23)
  421. o1 = TimezoneOffsetInfo.new(0, 0, :GMT)
  422. o2 = TimezoneOffsetInfo.new(0, 3600, :BST)
  423. period = TimezonePeriod.new(
  424. TimezoneTransitionInfo.new(o2, o1, 1111885200),
  425. TimezoneTransitionInfo.new(o1, o2, 1130634000))
  426. assert_equal(0, TestTimezone.new('Europe/London', period, [], dt).utc_to_local(dt).offset)
  427. assert_equal(0, TestTimezone.new('Europe/London', period, [], dt2).utc_to_local(dt2).offset)
  428. assert_equal(0, TestTimezone.new('Europe/London', period, [], t).utc_to_local(t).utc_offset)
  429. assert_equal('UTC', TestTimezone.new('Europe/London', period, [], t).utc_to_local(t).zone)
  430. assert_equal(0, TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2).utc_offset)
  431. assert_equal('UTC', TestTimezone.new('Europe/London', period, [], t2).utc_to_local(t2).zone)
  432. end
  433. def test_local_to_utc
  434. dt = DateTime.new(2005,6,18,16,24,23)
  435. dt2 = DateTime.new(2005,6,18,16,24,23)
  436. t = Time.utc(2005,6,18,16,24,23)
  437. t2 = Time.local(2005,6,18,16,24,23)
  438. ts = t.to_i
  439. o1 = TimezoneOffsetInfo.new(0, 0, :GMT)
  440. o2 = TimezoneOffsetInfo.new(0, 3600, :BST)
  441. period = TimezonePeriod.new(
  442. TimezoneTransitionInfo.new(o2, o1, 1111885200),
  443. TimezoneTransitionInfo.new(o1, o2, 1130634000))
  444. assert_equal(DateTime.new(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], dt).local_to_utc(dt))
  445. assert_equal(DateTime.new(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], dt2).local_to_utc(dt2))
  446. assert_equal(Time.utc(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t))
  447. assert_equal(Time.utc(2005,6,18,15,24,23), TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2))
  448. assert_equal(Time.utc(2005,6,18,15,24,23).to_i, TestTimezone.new('Europe/London', nil, [period], ts).local_to_utc(ts))
  449. end
  450. def test_local_to_utc_offset
  451. dt = DateTime.new(2005,6,18,16,24,23)
  452. dt2 = DateTime.new(2005,6,18,16,24,23).new_offset(Rational(5,24))
  453. t = Time.utc(2005,6,18,16,24,23)
  454. t2 = Time.local(2005,6,18,16,24,23)
  455. o1 = TimezoneOffsetInfo.new(0, 0, :GMT)
  456. o2 = TimezoneOffsetInfo.new(0, 3600, :BST)
  457. period = TimezonePeriod.new(
  458. TimezoneTransitionInfo.new(o2, o1, 1111885200),
  459. TimezoneTransitionInfo.new(o1, o2, 1130634000))
  460. assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dt).local_to_utc(dt).offset)
  461. assert_equal(0, TestTimezone.new('Europe/London', nil, [period], dt2).local_to_utc(dt2).offset)
  462. assert_equal(0, TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t).utc_offset)
  463. assert_equal('UTC', TestTimezone.new('Europe/London', nil, [period], t).local_to_utc(t).zone)
  464. assert_equal(0, TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2).utc_offset)
  465. assert_equal('UTC', TestTimezone.new('Europe/London', nil, [period], t2).local_to_utc(t2).zone)
  466. end
  467. def test_local_to_utc_invalid
  468. dt = DateTime.new(2004,4,4,2,30,0)
  469. tz = TestTimezone.new('America/New_York', nil, [], dt)
  470. assert_raises(PeriodNotFound) { tz.local_to_utc(dt) }
  471. t = Time.utc(2004,4,4,2,30,0)
  472. tz = TestTimezone.new('America/New_York', nil, [], t)
  473. assert_raises(PeriodNotFound) { tz.local_to_utc(t) }
  474. i = Time.utc(2004,4,4,2,30,0).to_i
  475. tz = TestTimezone.new('America/New_York', nil, [], i)
  476. assert_raises(PeriodNotFound) { tz.local_to_utc(i) }
  477. end
  478. def test_local_to_utc_ambiguous
  479. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  480. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  481. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  482. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  483. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  484. p1 = TimezonePeriod.new(t1, t2)
  485. p2 = TimezonePeriod.new(t2, t3)
  486. dt = DateTime.new(2004,10,31,1,30,0)
  487. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  488. assert_raises(AmbiguousTime) { tz.local_to_utc(dt) }
  489. t = Time.utc(2004,10,31,1,30,0)
  490. tz = TestTimezone.new('America/New_York', nil, [p1, p2], t)
  491. assert_raises(AmbiguousTime) { tz.local_to_utc(t) }
  492. i = Time.utc(2004,10,31,1,30,0).to_i
  493. tz = TestTimezone.new('America/New_York', nil, [p1, p2], i)
  494. assert_raises(AmbiguousTime) { tz.local_to_utc(i) }
  495. end
  496. def test_local_to_utc_not_found
  497. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  498. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  499. t1 = TimezoneTransitionInfo.new(o1, o2, 1067148000)
  500. t2 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  501. t3 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  502. p1 = TimezonePeriod.new(t1, t2)
  503. p2 = TimezonePeriod.new(t2, t3)
  504. dt = DateTime.new(2004,4,4,2,0,0)
  505. t = Time.utc(2004,4,4,2,30,0)
  506. i = Time.utc(2004,4,4,2,59,59).to_i
  507. dt_tz = TestTimezone.new('America/New_York', nil, [], dt)
  508. t_tz = TestTimezone.new('America/New_York', nil, [], t)
  509. i_tz = TestTimezone.new('America/New_York', nil, [], i)
  510. assert_raises(PeriodNotFound) { dt_tz.local_to_utc(dt) }
  511. assert_raises(PeriodNotFound) { t_tz.local_to_utc(t) }
  512. assert_raises(PeriodNotFound) { i_tz.local_to_utc(i) }
  513. end
  514. def test_local_to_utc_dst_flag_resolved
  515. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  516. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  517. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  518. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  519. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  520. p1 = TimezonePeriod.new(t1, t2)
  521. p2 = TimezonePeriod.new(t2, t3)
  522. dt = DateTime.new(2004,10,31,1,30,0)
  523. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  524. assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true))
  525. assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false))
  526. assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt, true) {|periods| raise BlockCalled, 'should not be called' })
  527. assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt, false) {|periods| raise BlockCalled, 'should not be called' })
  528. end
  529. def test_local_to_utc_dst_block_called
  530. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  531. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  532. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  533. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  534. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  535. p1 = TimezonePeriod.new(t1, t2)
  536. p2 = TimezonePeriod.new(t2, t3)
  537. dt = DateTime.new(2004,10,31,1,30,0)
  538. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  539. assert_raises(BlockCalled) {
  540. tz.local_to_utc(dt) {|periods|
  541. assert_equal([p1, p2], periods)
  542. # raise exception to test that the block was called
  543. raise BlockCalled, 'should be raised'
  544. }
  545. }
  546. assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt) {|periods| periods.first})
  547. assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt) {|periods| periods.last})
  548. assert_equal(DateTime.new(2004,10,31,5,30,0), tz.local_to_utc(dt) {|periods| [periods.first]})
  549. assert_equal(DateTime.new(2004,10,31,6,30,0), tz.local_to_utc(dt) {|periods| [periods.last]})
  550. end
  551. def test_local_to_utc_dst_cannot_resolve
  552. # At midnight local time on Aug 5 1915 in Warsaw, the clocks were put back
  553. # 24 minutes and both periods were non-DST. Hence the block should be
  554. # called regardless of the value of the Boolean dst parameter.
  555. o0 = TimezoneOffsetInfo.new(5040, 0, :LMT)
  556. o1 = TimezoneOffsetInfo.new(5040, 0, :WMT)
  557. o2 = TimezoneOffsetInfo.new(3600, 0, :CET)
  558. o3 = TimezoneOffsetInfo.new(3600, 3600, :CEST)
  559. t1 = TimezoneTransitionInfo.new(o1, o0, 288925853, 120)
  560. t2 = TimezoneTransitionInfo.new(o2, o1, 290485733, 120)
  561. t3 = TimezoneTransitionInfo.new(o3, o2, 29051813, 12)
  562. p1 = TimezonePeriod.new(t1, t2)
  563. p2 = TimezonePeriod.new(t2, t3)
  564. dt = DateTime.new(1915,8,4,23,40,0)
  565. tz = TestTimezone.new('Europe/Warsaw', nil, [p1, p2], dt)
  566. assert_raises(BlockCalled) do
  567. tz.local_to_utc(dt, true) do |periods|
  568. assert_equal([p1, p2], periods)
  569. raise BlockCalled, 'should be raised'
  570. end
  571. end
  572. assert_raises(BlockCalled) do
  573. tz.local_to_utc(dt, false) do |periods|
  574. assert_equal([p1, p2], periods)
  575. raise BlockCalled, 'should be raised'
  576. end
  577. end
  578. assert_equal(DateTime.new(1915,8,4,22,16,0), tz.local_to_utc(dt) {|periods| periods.first})
  579. assert_equal(DateTime.new(1915,8,4,22,40,0), tz.local_to_utc(dt) {|periods| periods.last})
  580. assert_equal(DateTime.new(1915,8,4,22,16,0), tz.local_to_utc(dt) {|periods| [periods.first]})
  581. assert_equal(DateTime.new(1915,8,4,22,40,0), tz.local_to_utc(dt) {|periods| [periods.last]})
  582. end
  583. def test_local_to_utc_block_ambiguous
  584. o1 = TimezoneOffsetInfo.new(-18000, 0, :EST)
  585. o2 = TimezoneOffsetInfo.new(-18000, 3600, :EDT)
  586. t1 = TimezoneTransitionInfo.new(o2, o1, 1081062000)
  587. t2 = TimezoneTransitionInfo.new(o1, o2, 1099202400)
  588. t3 = TimezoneTransitionInfo.new(o2, o1, 1112511600)
  589. p1 = TimezonePeriod.new(t1, t2)
  590. p2 = TimezonePeriod.new(t2, t3)
  591. dt = DateTime.new(2004,10,31,1,30,0)
  592. tz = TestTimezone.new('America/New_York', nil, [p1, p2], dt)
  593. dt = DateTime.new(2004,10,31,1,30,0)
  594. tz = Timezone.get('America/New_York')
  595. assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| nil} }
  596. assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| periods} }
  597. assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| []} }
  598. assert_raises(AmbiguousTime) { tz.local_to_utc(dt) {|periods| raise AmbiguousTime, 'Ambiguous time'} }
  599. end
  600. def test_now
  601. assert_kind_of(Time, Timezone.get('Europe/London').now)
  602. end
  603. def test_current_period
  604. assert_kind_of(TimezonePeriod, Timezone.get('Europe/London').current_period)
  605. end
  606. def test_current_period_and_time
  607. current = Timezone.get('Europe/London').current_period_and_time
  608. assert_equal(2, current.length)
  609. assert_kind_of(Time, current[0])
  610. assert_kind_of(TimezonePeriod, current[1])
  611. end
  612. def test_current_time_and_period
  613. current = Timezone.get('Europe/London').current_time_and_period
  614. assert_equal(2, current.length)
  615. assert_kind_of(Time, current[0])
  616. assert_kind_of(TimezonePeriod, current[1])
  617. end
  618. def test_compare
  619. assert_equal(0, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/London'))
  620. assert_equal(-1, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/london'))
  621. assert_equal(-1, TestTimezone.new('Europe/London') <=> TestTimezone.new('Europe/Paris'))
  622. assert_equal(1, TestTimezone.new('Europe/Paris') <=> TestTimezone.new('Europe/London'))
  623. assert_equal(-1, TestTimezone.new('America/New_York') <=> TestTimezone.new('Europe/Paris'))
  624. assert_equal(1, TestTimezone.new('Europe/Paris') <=> TestTimezone.new('America/New_York'))
  625. end
  626. def test_equality
  627. assert_equal(true, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/London'))
  628. assert_equal(false, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/london'))
  629. assert_equal(false, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/Paris'))
  630. assert(!(TestTimezone.new('Europe/London') == Object.new))
  631. end
  632. def test_eql
  633. assert_equal(true, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/London')))
  634. assert_equal(false, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/london')))
  635. assert_equal(false, TestTimezone.new('Europe/London').eql?(TestTimezone.new('Europe/Paris')))
  636. assert(!TestTimezone.new('Europe/London').eql?(Object.new))
  637. end
  638. def test_hash
  639. assert_equal('Europe/London'.hash, TestTimezone.new('Europe/London').hash)
  640. assert_equal('America/New_York'.hash, TestTimezone.new('America/New_York').hash)
  641. end
  642. def test_marshal_data
  643. tz = Timezone.get('Europe/London')
  644. assert_kind_of(DataTimezone, tz)
  645. assert_same(tz, Marshal.load(Marshal.dump(tz)))
  646. end
  647. def test_marshal_linked
  648. tz = Timezone.get('UTC')
  649. assert_kind_of(LinkedTimezone, tz)
  650. assert_same(tz, Marshal.load(Marshal.dump(tz)))
  651. end
  652. def test_strftime_datetime
  653. tz = Timezone.get('Europe/London')
  654. assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', DateTime.new(1965, 7, 15, 22, 12, 2)))
  655. assert_equal('BST', tz.strftime('%Z', DateTime.new(1965, 7, 15, 22, 12, 2)))
  656. assert_equal('%ZBST', tz.strftime('%%Z%Z', DateTime.new(1965, 7, 15, 22, 12, 2)))
  657. assert_equal('BST BST', tz.strftime('%Z %Z', DateTime.new(1965, 7, 15, 22, 12, 2)))
  658. end
  659. def test_strftime_time
  660. tz = Timezone.get('Europe/London')
  661. assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', Time.utc(2006, 7, 15, 22, 12, 2)))
  662. assert_equal('BST', tz.strftime('%Z', Time.utc(2006, 7, 15, 22, 12, 2)))
  663. assert_equal('%ZBST', tz.strftime('%%Z%Z', Time.utc(2006, 7, 15, 22, 12, 2)))
  664. assert_equal('BST BST', tz.strftime('%Z %Z', Time.utc(2006, 7, 15, 22, 12, 2)))
  665. end
  666. def test_strftime_int
  667. tz = Timezone.get('Europe/London')
  668. assert_equal('23:12:02 BST', tz.strftime('%H:%M:%S %Z', Time.utc(2006, 7, 15, 22, 12, 2).to_i))
  669. assert_equal('BST', tz.strftime('%Z', Time.utc(2006, 7, 15, 22, 12, 2).to_i))
  670. assert_equal('%ZBST', tz.strftime('%%Z%Z', Time.utc(2006, 7, 15, 22, 12, 2).to_i))
  671. assert_equal('BST BST', tz.strftime('%Z %Z', Time.utc(2006, 7, 15, 22, 12, 2).to_i))
  672. end
  673. end