提交 53c1cd6c 编写于 作者: X Xavier Noria

let Time.time_with_datetime_fallback handle properly years in the range 0..138

上级 38da0ace
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 @@ def to_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")
......
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 @@ def days_in_month(month, year = now.year)
# (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>.
......
......@@ -20,6 +20,13 @@ def test_readable_inspect
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 @@ def test_end_of_month
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
......
......@@ -40,6 +40,11 @@ def test_to_time
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
......
......@@ -587,6 +587,13 @@ def test_time_with_datetime_fallback
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册