diff options
Diffstat (limited to 'activesupport')
5 files changed, 30 insertions, 4 deletions
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 a9f821b01e..24168c7825 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -1,5 +1,6 @@ require 'active_support/inflector' require 'active_support/core_ext/time/conversions' +require 'active_support/core_ext/date_time/calculations' class DateTime # Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows @@ -72,6 +73,11 @@ class DateTime self end unless method_defined?(:to_datetime) + def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0) + offset = utc_or_local.to_sym == :local ? local_offset : 0 + civil(year, month, day, hour, min, sec, offset) + end + # Converts datetime to an appropriate format for use in XML def xmlschema strftime("%Y-%m-%dT%H:%M:%S%Z") diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 98906bc5c0..2b47ecd543 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -1,6 +1,7 @@ require 'active_support/duration' require 'active_support/core_ext/date/acts_like' require 'active_support/core_ext/date/calculations' +require 'active_support/core_ext/date_time/conversions' class Time COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] @@ -23,10 +24,11 @@ class Time # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture); # otherwise returns a DateTime def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0) - ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec) + time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec) + # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138. + time.year == year ? time : ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec) rescue - offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0 - ::DateTime.civil(year, month, day, hour, min, sec, offset) + ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec) end # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>. diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index c403d7fb11..1f94b80edc 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -20,6 +20,13 @@ class DateExtCalculationsTest < Test::Unit::TestCase 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 + silence_warnings do + 0.upto(138) do |year| + [:utc, :local].each do |format| + assert_equal year, Date.new(year).to_time(format).year + end + end + end end def test_to_datetime @@ -89,7 +96,6 @@ class DateExtCalculationsTest < Test::Unit::TestCase assert_equal Date.new(2005,3,31), Date.new(2005,3,20).end_of_month assert_equal Date.new(2005,2,28), Date.new(2005,2,20).end_of_month assert_equal Date.new(2005,4,30), Date.new(2005,4,20).end_of_month - end def test_beginning_of_year diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index 278c05797b..f9af059acd 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -40,6 +40,11 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase assert_equal DateTime.new(2005, 2, 21, 10, 11, 12, Rational(-5, 24)), DateTime.new(2005, 2, 21, 10, 11, 12, Rational(-5, 24)).to_time end + def test_civil_from_format + assert_equal DateTime.civil(2010, 5, 4, 0, 0, 0, DateTime.local_offset), DateTime.civil_from_format(:local, 2010, 5, 4) + assert_equal DateTime.civil(2010, 5, 4, 0, 0, 0, 0), DateTime.civil_from_format(:utc, 2010, 5, 4) + end + def test_seconds_since_midnight assert_equal 1,DateTime.civil(2005,1,1,0,0,1).seconds_since_midnight assert_equal 60,DateTime.civil(2005,1,1,0,1,0).seconds_since_midnight diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index c24c8619c6..342d6ab577 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -587,6 +587,13 @@ class TimeExtCalculationsTest < Test::Unit::TestCase DateTime.civil(2039, 2, 21, 17, 44, 30, 0, 0) assert_equal ::Date::ITALY, Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30, 1).start # use Ruby's default start value end + silence_warnings do + 0.upto(138) do |year| + [:utc, :local].each do |format| + assert_equal year, Time.time_with_datetime_fallback(format, year).year + end + end + end end def test_utc_time |