From b7d2dae6dcf00b38a1dba8687d6b70d863da915e Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Wed, 30 May 2007 06:24:32 +0000
Subject: DateTime#to_time converts to Time unless out of range.
 Date#to_datetime and Date#to_s(:rfc822). Closes #8512.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6902 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
---
 activesupport/CHANGELOG                                |  4 ++++
 .../lib/active_support/core_ext/date/conversions.rb    | 18 +++++++++++-------
 .../active_support/core_ext/date_time/conversions.rb   | 10 +++++++++-
 .../lib/active_support/core_ext/time/conversions.rb    |  3 ++-
 activesupport/test/core_ext/date_ext_test.rb           |  8 +++++---
 activesupport/test/core_ext/date_time_ext_test.rb      |  6 ++++++
 6 files changed, 37 insertions(+), 12 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index ca8d43903a..d3af47bc6a 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,9 @@
 *SVN*
 
+* DateTime#to_time converts to Time unless out of range.  #8512 [Geoff Buesing]
+
+* Date#to_datetime, #to_s(:rfc822).  #8512 [Geoff Buesing]
+
 * Time durations use since instead of + for accuracy.  #8513 [Geoff Buesing]
 
 * escape <'s and >'s in JSON strings. #8371 [Rick]
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index 01dd8461e4..25745b0f8b 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -7,7 +7,8 @@ module ActiveSupport #:nodoc:
           :short        => "%e %b",
           :long         => "%B %e, %Y",
           :db           => "%Y-%m-%d",
-          :long_ordinal => lambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") } # => "April 25th, 2007"
+          :long_ordinal => lambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") }, # => "April 25th, 2007"
+          :rfc822       => "%e %b %Y"
         }
 
         def self.included(klass) #:nodoc:
@@ -27,17 +28,20 @@ module ActiveSupport #:nodoc:
           end
         end
 
-        # To be able to keep Dates and Times interchangeable on conversions
+        # To be able to keep Times, Dates and DateTimes interchangeable on conversions
         def to_date
           self
         end
 
+        # Converts self to a Ruby Time object; time is set to beginning of day
+        # Timezone can either be :local or :utc  (default :local)
         def to_time(form = :local)
-          if respond_to?(:hour)
-            ::Time.send(form, year, month, day, hour, min, sec)
-          else
-            ::Time.send(form, year, month, day)
-          end
+          ::Time.send("#{form}_time", year, month, day)
+        end
+        
+        # Converts self to a Ruby DateTime object; time is set to beginning of day
+        def to_datetime
+          ::DateTime.civil(year, month, day, 0, 0, 0, 0, 0)
         end
 
         def xmlschema
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 0b66593499..1b78a72eea 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -20,11 +20,19 @@ module ActiveSupport #:nodoc:
           end
         end
 
+        # Converts self to a Ruby Date object; time portion is discarded
         def to_date
           ::Date.new(year, month, day)
         end
 
-        # To be able to keep Times and DateTimes interchangeable on conversions
+        # Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
+        # If self.offset is 0, then will attempt to cast as a utc time; otherwise will attempt to cast in local time zone
+        def to_time
+          method = if self.offset == 0 then 'utc' else 'local' end
+          ::Time.send(method, year, month, day, hour, min, sec) rescue self
+        end        
+
+        # To be able to keep Times, Dates and DateTimes interchangeable on conversions
         def to_datetime
           self
         end
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index 3945fe8f8c..7829c2e581 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -29,11 +29,12 @@ module ActiveSupport #:nodoc:
           end
         end
 
+        # Converts self to a Ruby Date object; time portion is discarded
         def to_date
           ::Date.new(year, month, day)
         end
 
-        # To be able to keep Dates and Times interchangeable on conversions
+        # To be able to keep Times, Dates and DateTimes interchangeable on conversions
         def to_time
           self
         end
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index 6a0508b8c4..3557c11748 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -6,14 +6,16 @@ class DateExtCalculationsTest < Test::Unit::TestCase
     assert_equal "February 21, 2005",   Date.new(2005, 2, 21).to_s(:long)
     assert_equal "February 21st, 2005", Date.new(2005, 2, 21).to_s(:long_ordinal)
     assert_equal "2005-02-21",          Date.new(2005, 2, 21).to_s(:db)
+    assert_equal "21 Feb 2005",         Date.new(2005, 2, 21).to_s(:rfc822)
   end
 
   def test_to_time
     assert_equal Time.local(2005, 2, 21), Date.new(2005, 2, 21).to_time
+    assert_equal Time.local_time(2039, 2, 21), Date.new(2039, 2, 21).to_time
   end
-
-  def test_to_time_on_datetime
-    assert_equal Time.local(2005, 2, 21, 10, 11, 12), DateTime.new(2005, 2, 21, 10, 11, 12).to_time
+  
+  def test_to_datetime
+    assert_equal DateTime.civil(2005, 2, 21), Date.new(2005, 2, 21).to_datetime
   end
 
   def test_to_date
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 0aacf123c3..b5d80295f0 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -21,6 +21,12 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
   def test_to_date
     assert_equal Date.new(2005, 2, 21), DateTime.new(2005, 2, 21).to_date
   end
+  
+  def test_to_time
+    assert_equal Time.utc(2005, 2, 21, 10, 11, 12), DateTime.new(2005, 2, 21, 10, 11, 12, 0, 0).to_time
+    assert_equal Time.local(2005, 2, 21, 10, 11, 12), DateTime.new(2005, 2, 21, 10, 11, 12, Rational(-5, 24), 0).to_time
+    assert_equal Time.utc_time(2039, 2, 21, 10, 11, 12), DateTime.new(2039, 2, 21, 10, 11, 12, 0, 0).to_time
+  end
 
   def test_seconds_since_midnight
     assert_equal 1,DateTime.civil(2005,1,1,0,0,1).seconds_since_midnight
-- 
cgit v1.2.3