From f73f9e42f4e6987ff53e3bd5e53a5040b04f9f36 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 24 Feb 2005 11:56:09 +0000 Subject: [PATCH] Made TimeZone even more delicious #709 git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@787 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/active_support/values/time_zone.rb | 37 ++++++++++++++----- activesupport/test/time_zone_test.rb | 16 ++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 3f524c4759..3aa135c28f 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -22,13 +22,14 @@ def initialize(name, utc_offset) # Returns the offset of this time zone as a formatted string, of the # format "+HH:MM". If the offset is zero, this returns the empty - # string. - def formatted_offset + # string. If +colon+ is false, a colon will not be inserted into the + # result. + def formatted_offset( colon=true ) return "" if utc_offset == 0 sign = (utc_offset < 0 ? -1 : 1) hours = utc_offset.abs / 3600 minutes = (utc_offset.abs % 3600) / 60 - "%+03d:%02d" % [ hours * sign, minutes ] + "%+03d%s%02d" % [ hours * sign, colon ? ":" : "", minutes ] end # Compute and return the current time, in the time zone represented by @@ -45,8 +46,15 @@ def today # Adjust the given time to the time zone represented by +self+. def adjust(time) time = time.to_time - offset = time.utc_offset - time + utc_offset - offset + time + utc_offset - time.utc_offset + end + + # Reinterprets the given time value as a time in the current time + # zone, and then adjusts it to return the corresponding time in the + # local time zone. + def unadjust(time) + time = Time.local(*time.to_time.to_a) + time - utc_offset + time.utc_offset end # Compare this time zone to the parameter. The two are comapred first on @@ -142,10 +150,21 @@ def all @@zones end - # Locate a specific time zone object by the name it was given. Returns - # +nil+ if no such time zone is known to the system. - def [](name) - all.find { |z| z.name == name } + # Locate a specific time zone object. If the argument is a string, it + # is interpreted to mean the name of the timezone to locate. If it is a + # numeric value it is either the hour offset, or the second offset, of the + # timezone to find. (The first one with that offset will be returned.) + # Returns +nil+ if no such time zone is known to the system. + def [](arg) + case arg + when String + all.find { |z| z.name == arg } + when Numeric + arg *= 3600 if arg.abs <= 13 + all.find { |z| z.utc_offset == arg.to_i } + else + raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}" + end end # A regular expression that matches the names of all time zones in diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 66f1a1b058..3e35c327e0 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -6,6 +6,10 @@ class MockTime def self.now Time.utc( 2004, 7, 25, 14, 49, 00 ) end + + def self.local(*args) + Time.utc(*args) + end end TimeZone::Time = MockTime @@ -25,6 +29,11 @@ def test_now assert_equal Time.local(2004,7,25,15,59,00).to_a[0,6], zone.now.to_a[0,6] end + def test_today + zone = TimeZone.create( "Test", 43200 ) + assert_equal Date.new(2004,7,26), zone.today + end + def test_adjust_negative zone = TimeZone.create( "Test", -4200 ) assert_equal Time.utc(2004,7,24,23,55,0), zone.adjust(Time.utc(2004,7,25,1,5,0)) @@ -35,6 +44,13 @@ def test_adjust_positive assert_equal Time.utc(2004,7,26,1,5,0), zone.adjust(Time.utc(2004,7,25,23,55,0)) end + def test_unadjust + zone = TimeZone.create( "Test", 4200 ) + expect = Time.utc(2004,7,24,23,55,0).to_a[0,6] + actual = zone.unadjust(Time.utc(2004,7,25,1,5,0)).to_a[0,6] + assert_equal expect, actual + end + def test_zone_compare zone1 = TimeZone.create( "Test1", 4200 ) zone2 = TimeZone.create( "Test1", 5600 ) -- GitLab