require 'timezone' require 'timezone/zone' require 'minitest/autorun' require "mocha/setup" require 'timecop' class TimezoneTest < ::Minitest::Unit::TestCase def test_valid_timezone refute_nil(Timezone::Zone.new(:zone => 'Australia/Sydney')) end def test_nil_timezone assert_raises Timezone::Error::NilZone do Timezone::Zone.new :zone => nil end end def test_invalid_timezone assert_raises Timezone::Error::InvalidZone do Timezone::Zone.new :zone => 'Foo/Bar' end end def test_timezone_list list = Timezone::Zone.list "Australia/Sydney", "America/Chicago" assert list.is_a?(Array) assert list.count == 2 assert list.first.is_a?(Hash) assert(list.any?{ |l| l[:zone] == 'Australia/Sydney' }) end def test_timezone_list_current_time Timecop.freeze(Time.new(2012,2,2,0,0,0)) do assert !Timezone::Zone.list('EST5EDT').first[:dst] end Timecop.freeze(Time.new(2013,6,6,0,0,0)) do assert Timezone::Zone.list('EST5EDT').first[:dst] end end def test_timezone_custom_list_order Timezone::Configure.order_list_by = :title Timezone::Configure.replace "America/Chicago", with: "Chicago" list = Timezone::Zone.list "Australia/Sydney", "America/Chicago" assert list.first[:title] == "Australia/Sydney" assert list.last[:title] == "Chicago" assert list.last[:zone] == "America/Chicago" end def test_timezone_default_list Timezone::Configure.default_for_list = "America/Chicago", "Australia/Sydney" list = Timezone::Zone.list assert list.count == 2 assert(list.any?{ |l| l.has_value?("Australia/Sydney") }) end def test_timezone_names zones = Timezone::Zone.names assert zones.is_a?(Array) assert zones.count > 0 assert zones.include? "Australia/Sydney" end def time_timezone_equivalence gmt = Timezone::Zone.new :zone => 'GMT' australia = Timezone::Zone.new :zone => 'Australia/Sydney' assert_equal(gmt, Timezone::Zone.new(:zone => 'GMT')) assert gmt <= australia assert gmt < australia end def utc_offset(zone, year, month, day) Timezone::Zone.new(:zone => zone).utc_offset(Time.new(year, month, day)) end def test_getting_utc_offset assert_equal(36000, utc_offset('Australia/Sydney', 2011, 06, 05)) assert_equal(-25200, utc_offset('America/Los_Angeles', 2011, 06, 05)) assert_equal(20700, utc_offset('Asia/Kathmandu', 2011, 06, 05)) assert_equal(-18000, utc_offset('America/New_York', 2011, 01, 11)) assert_equal(-14400, utc_offset('America/New_York', 2011, 06, 11)) end def dst?(zone, year, month, day) Timezone::Zone.new(:zone => zone).dst?(Time.new(year, month, day)) end def test_getting_dst refute dst?('Australia/Sydney', 2011, 06, 05) assert dst?('America/Los_Angeles', 2011, 06, 05) refute dst?('Asia/Kathmandu', 2011, 06, 05) refute dst?('America/New_York', 2011, 01, 11) assert dst?('America/New_York', 2011, 06, 11) end def test_loading_GMT_timezone timezone = Timezone::Zone.new :zone => 'GMT' assert_equal Time.now.utc.to_i, timezone.time(Time.now).to_i end def test_loading_historical_time timezone = Timezone::Zone.new :zone => 'America/Los_Angeles' local = Time.strptime('2011-02-11T13:20:00Z', '%Y-%m-%dT%H:%M:%SZ') utc = Time.strptime('2011-02-11T21:20:00Z', '%Y-%m-%dT%H:%M:%SZ') assert_equal local.to_i, timezone.time(utc).to_i end # http://www.timeanddate.com/worldclock/clockchange.html?n=137&year=2011 def test_historical_time_change_in_la_forward timezone = Timezone::Zone.new :zone => 'America/Los_Angeles' local = Time.strptime('2011-03-13T01:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('2011-03-13T09:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i timezone = Timezone::Zone.new :zone => 'America/Los_Angeles' local = Time.strptime('2011-03-13T03:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('2011-03-13T10:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i end # http://www.timeanddate.com/worldclock/clockchange.html?n=137&year=2011 def test_historical_time_change_in_la_backward timezone = Timezone::Zone.new :zone => 'America/Los_Angeles' local = Time.strptime('2011-11-06T01:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('2011-11-06T08:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i timezone = Timezone::Zone.new :zone => 'America/Los_Angeles' local = Time.strptime('2011-11-06T01:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('2011-11-06T09:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i end # http://www.timeanddate.com/worldclock/clockchange.html?n=2364&year=1940 def test_historical_time_change_in_hebron timezone = Timezone::Zone.new :zone => 'Asia/Hebron' local = Time.strptime('1940-05-31T23:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('1940-05-31T21:59:59 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i timezone = Timezone::Zone.new :zone => 'Asia/Hebron' local = Time.strptime('1940-06-01T01:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') utc = Time.strptime('1940-05-31T22:00:00 UTC', '%Y-%m-%dT%H:%M:%S %Z') assert_equal local.to_i, timezone.time(utc).to_i end def test_loading_half_hour_timezone timezone = Timezone::Zone.new :zone => 'Asia/Kathmandu' utc = Time.utc(2011, 1, 4, 3, 51, 29) local = Time.utc(2011, 1, 4, 9, 36, 29) assert_equal local.to_i, timezone.time(utc).to_i end # Testing is done with strings since two times can be equivalent even if # their offsets do not match, and we want to test that the time and offsets # are equivalent. def test_time_with_offset timezone = Timezone::Zone.new :zone => 'Asia/Kathmandu' utc = Time.utc(2011, 1, 4, 3, 51, 29) local = Time.new(2011, 1, 4, 9, 36, 29, 20700) assert_equal local.to_s, timezone.time_with_offset(utc).to_s zone = Timezone::Zone.new(:zone => 'America/Los_Angeles') utc = Time.utc(2014,12,15,22,00,00) local = Time.new(2014,12,15,14,00,00,'-08:00') assert_equal local.to_s, zone.time_with_offset(utc).to_s utc = Time.utc(2014,4,5,22,00,00) local = Time.new(2014,4,5,15,00,00,'-07:00') assert_equal local.to_s, zone.time_with_offset(utc).to_s end def test_australian_timezone_with_dst timezone = Timezone::Zone.new :zone => 'Australia/Adelaide' utc = Time.utc(2010, 12, 23, 19, 37, 15) local = Time.utc(2010, 12, 24, 6, 7, 15) assert_equal local.to_i, timezone.time(utc).to_i end def test_local_to_utc timezone = Timezone::Zone.new(:zone => 'America/Los_Angeles') # Time maps to two rules - we pick the first local = Time.utc(2015,11,1,1,50,0) utc = Time.utc(2015,11,1,8,50,0) assert_equal(utc.to_s, timezone.local_to_utc(local).to_s) # Time is above the maximum - we pick the last rule local = Time.utc(3000,1,1,0,0,0) utc = Time.utc(3000,1,1,8,0,0) assert_equal(utc.to_s, timezone.local_to_utc(local).to_s) # Time maps to a single rule - we pick that rule local = Time.utc(2015,11,1,0,1,0) utc = Time.utc(2015,11,1,7,1,0) assert_equal(utc.to_s, timezone.local_to_utc(local).to_s) # Time is missing - we pick the first closest rule local = Time.utc(2015,3,8,2,50,0) utc = Time.utc(2015,3,8,9,50,0) assert_equal(utc.to_s, timezone.local_to_utc(local).to_s) end def test_configure_url_default Timezone::Configure.begin{ |c| c.google_api_key = nil } assert_equal 'api.geonames.org', Timezone::Configure.url end def test_configure_url_custom Timezone::Configure.begin { |c| c.google_api_key = nil } Timezone::Configure.begin { |c| c.geonames_url = 'www.newtimezoneserver.com' } assert_equal 'www.newtimezoneserver.com', Timezone::Configure.url # clean up url after test Timezone::Configure.begin { |c| c.geonames_url = nil } end def test_utc_offset_without_dst timezone = Timezone::Zone.new :zone => 'Europe/Helsinki' # just before DST starts utc = Time.utc(2012, 3, 25, 0, 59, 59) assert_equal timezone.utc_offset(utc), 7200 # on the second DST ends utc = Time.utc(2012, 10, 28, 1, 0, 0) assert_equal timezone.utc_offset(utc), 7200 end def test_utc_offset_with_dst timezone = Timezone::Zone.new :zone => 'Europe/Helsinki' # on the second DST starts utc = Time.utc(2012, 3, 25, 1, 0, 0) assert_equal timezone.utc_offset(utc), 10800 # right before DST end utc = Time.utc(2012, 10, 28, 0, 59, 59) assert_equal timezone.utc_offset(utc), 10800 end def test_active_support_timezone timezone = Timezone::Zone.new(:zone => 'Australia/Adelaide') assert_equal 'Australia/Adelaide', timezone.zone assert_equal 'Adelaide', timezone.active_support_time_zone timezone = Timezone::Zone.new(:zone => 'America/Phoenix') assert_equal 'America/Phoenix', timezone.zone assert_equal 'Arizona', timezone.active_support_time_zone timezone = Timezone::Zone.new(:zone => 'America/Anchorage') assert_equal 'America/Anchorage', timezone.zone assert_equal 'America/Anchorage', timezone.active_support_time_zone end EQUIVALENCE_METHODS = [ :time, :local_to_utc, :time_with_offset, :dst?, :utc_offset ] def check_equivalence(zone, time, other) tz = Timezone::Zone.new(:zone => zone) EQUIVALENCE_METHODS.each do |m| assert_equal(tz.public_send(m, time), tz.public_send(m, other)) end end def test_date_equivalence time = Time.new(2011, 2, 3, 0, 0, 0) date = Date.new(2011, 2, 3) check_equivalence('America/Los_Angeles', time, date) time = Time.new(2011, 6, 3, 0, 0, 0) date = Date.new(2011, 6, 3) check_equivalence('America/Los_Angeles', time, date) end def test_datetime_equivalence time = Time.new(2011, 2, 3, 13, 5, 0) datetime = DateTime.new(2011, 2, 3, 13, 5, 0) check_equivalence('America/Los_Angeles', time, datetime) time = Time.new(2011, 6, 3, 13, 5, 0) datetime = DateTime.new(2011, 6, 3, 13, 5, 0) check_equivalence('America/Los_Angeles', time, datetime) end end