PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Languages/Ruby/Tests/Libraries/TZInfoTests/tc_timezone.rb

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