From b132413885cff785851980dc1740a003109214b7 Mon Sep 17 00:00:00 2001 From: Geoff Buesing Date: Mon, 17 Mar 2008 03:45:32 +0000 Subject: Adding TimeZone#at and DateTime#to_f git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9042 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/CHANGELOG | 2 ++ .../active_support/core_ext/date_time/conversions.rb | 6 ++++++ activesupport/lib/active_support/time_with_zone.rb | 2 +- activesupport/lib/active_support/values/time_zone.rb | 14 ++++++++++++-- activesupport/test/core_ext/date_time_ext_test.rb | 5 +++++ activesupport/test/time_zone_test.rb | 19 +++++++++++++++++++ 6 files changed, 45 insertions(+), 3 deletions(-) (limited to 'activesupport') diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 6b1130a32a..90ba8b5f04 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Adding TimeZone#at and DateTime#to_f [Geoff Buesing] + * TimeWithZone responds to Ruby 1.9 weekday-named query methods [Geoff Buesing] * TimeWithZone caches TZInfo::TimezonePeriod used for time conversion so that it can be reused, and enforces DST rules correctly when instance is created from a local time [Geoff Buesing] diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index 7e78550f7c..9b6d6e5e90 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -78,6 +78,12 @@ module ActiveSupport #:nodoc: def xmlschema strftime("%Y-%m-%dT%H:%M:%S%Z") end if RUBY_VERSION < '1.9' + + # Converts self to a floating-point number of seconds since the Unix epoch + def to_f + days_since_unix_epoch = self - ::DateTime.civil(1970) + (days_since_unix_epoch * 86_400).to_f + end end end end diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 10c3543d6e..ca82c2e004 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -160,7 +160,7 @@ module ActiveSupport end unless RUBY_VERSION < '1.9' def to_a - time.to_a[0, 8].push(dst?, zone) + [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone] end def to_f diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 401b669a0a..391ebc644e 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -178,7 +178,7 @@ class TimeZone begin # the following methods depend on the tzinfo gem require_library_or_gem "tzinfo" unless Object.const_defined?(:TZInfo) - # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+. Example: + # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from given values. Example: # # Time.zone = "Hawaii" # => "Hawaii" # Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00 @@ -186,6 +186,16 @@ class TimeZone time = Time.utc_time(*args) ActiveSupport::TimeWithZone.new(nil, self, time) end + + # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from number of seconds since the Unix epoch. Example: + # + # Time.zone = "Hawaii" # => "Hawaii" + # Time.utc(2000).to_f # => 946684800.0 + # Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + def at(secs) + utc = Time.at(secs).utc rescue DateTime.civil(1970).since(secs) + utc.in_time_zone(self) + end # Returns an ActiveSupport::TimeWithZone instance representing the current time # in the time zone represented by +self+. Example: @@ -234,7 +244,7 @@ class TimeZone rescue LoadError # Tzinfo gem is not available # re-raise LoadError only when a tzinfo-dependent method is called: - %w(local now today utc_to_local local_to_utc period_for_utc period_for_local tzinfo).each do |method| + %w(local at now today utc_to_local local_to_utc period_for_utc period_for_local tzinfo).each do |method| define_method(method) {|*args| raise LoadError, "TZInfo gem is required for TimeZone##{method}. `gem install tzinfo` and try again."} end end diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index cb9b6530c9..42aaf0ebad 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -271,6 +271,11 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase assert_equal 0, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0), TimeZone['UTC'] ) assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), TimeZone['UTC'] )) end + + def test_to_f + assert_equal 946684800.0, DateTime.civil(2000).to_f + assert_equal 946684800.0, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_f + end protected def with_env_tz(new_tz = 'US/Eastern') diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 3ae88db9dd..f5e4e5478a 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -185,6 +185,25 @@ class TimeZoneTest < Test::Unit::TestCase assert_equal true, twz.dst? assert_equal 'EDT', twz.zone end + + def test_at + zone = TimeZone['Eastern Time (US & Canada)'] + secs = 946684800.0 + twz = zone.at(secs) + assert_equal Time.utc(1999,12,31,19), twz.time + assert_equal Time.utc(2000), twz.utc + assert_equal zone, twz.time_zone + assert_equal secs, twz.to_f + end + + def test_at_with_old_date + zone = TimeZone['UTC'] + secs = -3786825600.0 + twz = zone.at(secs) + assert_equal [0,0,0,1,1,1850], twz.to_a[0,6] + assert_equal zone, twz.time_zone + assert_equal secs, twz.to_f + end protected def with_env_tz(new_tz = 'US/Eastern') -- cgit v1.2.3