提交 b845826d 编写于 作者: C Charlie Somerville

Merge pull request #2 from github/2-3-github+fixed-db-timezones

[2.3] Always convert Time and DateTime objects to local before converting to string
...@@ -12,7 +12,7 @@ def test_saves_both_date_and_time ...@@ -12,7 +12,7 @@ def test_saves_both_date_and_time
task.save! task.save!
# check against Time.local_time, since some platforms will return a Time instead of a DateTime # check against Time.local_time, since some platforms will return a Time instead of a DateTime
assert_equal Time.local_time(*time_values), Task.find(task.id).starting assert_equal DateTime.civil(*time_values), Task.find(task.id).starting
end end
def test_assign_empty_date_time def test_assign_empty_date_time
......
...@@ -4,7 +4,20 @@ module Time #:nodoc: ...@@ -4,7 +4,20 @@ module Time #:nodoc:
# Converting times to formatted strings, dates, and datetimes. # Converting times to formatted strings, dates, and datetimes.
module Conversions module Conversions
DATE_FORMATS = { DATE_FORMATS = {
:db => "%Y-%m-%d %H:%M:%S", :db => lambda { |time|
time = time.utc.to_time
if !defined?(ActiveRecord::Base.default_timezone) || ActiveRecord::Base.default_timezone == :local
# our DB is in local time (ugh), so make sure the time object is
# converted to local time before converting it to a db string
#
# also we have to do this ridiculous dance to ensure that we can
# turn any given DateTime object into something in localtime.
time = time.getlocal
end
time.strftime("%Y-%m-%d %H:%M:%S")
},
:number => "%Y%m%d%H%M%S", :number => "%Y%m%d%H%M%S",
:time => "%H:%M", :time => "%H:%M",
:short => "%d %b %H:%M", :short => "%d %b %H:%M",
...@@ -48,7 +61,7 @@ def to_formatted_s(format = :default) ...@@ -48,7 +61,7 @@ def to_formatted_s(format = :default)
return to_default_s unless formatter = DATE_FORMATS[format] return to_default_s unless formatter = DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
end end
# Returns the UTC offset as an +HH:MM formatted string. # Returns the UTC offset as an +HH:MM formatted string.
# #
# Time.local(2000).formatted_offset # => "-06:00" # Time.local(2000).formatted_offset # => "-06:00"
......
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
class DateTimeExtCalculationsTest < Test::Unit::TestCase class DateTimeExtCalculationsTest < Test::Unit::TestCase
def test_to_s def test_to_s
datetime = DateTime.new(2005, 2, 21, 14, 30, 0, 0) # this is how you create a local DateTime. lol.
datetime = Time.new(2005, 2, 21, 14, 30, 0).to_datetime
assert_equal "2005-02-21 14:30:00", datetime.to_s(:db) assert_equal "2005-02-21 14:30:00", datetime.to_s(:db)
assert_equal "14:30", datetime.to_s(:time) assert_equal "14:30", datetime.to_s(:time)
assert_equal "21 Feb 14:30", datetime.to_s(:short) assert_equal "21 Feb 14:30", datetime.to_s(:short)
assert_equal "February 21, 2005 14:30", datetime.to_s(:long) assert_equal "February 21, 2005 14:30", datetime.to_s(:long)
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.to_s(:rfc822) assert_equal "Mon, 21 Feb 2005 14:30:00 #{datetime.formatted_offset(false)}", datetime.to_s(:rfc822)
assert_equal "February 21st, 2005 14:30", datetime.to_s(:long_ordinal) assert_equal "February 21st, 2005 14:30", datetime.to_s(:long_ordinal)
assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/, datetime.to_s) assert_equal "2005-02-21T14:30:00#{datetime.formatted_offset(true)}", datetime.to_s
end end
def test_readable_inspect def test_readable_inspect
...@@ -229,7 +231,7 @@ def test_past_with_offset ...@@ -229,7 +231,7 @@ def test_past_with_offset
assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).past? assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).past?
assert_equal false, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).past? assert_equal false, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).past?
end end
def test_past_without_offset def test_past_without_offset
DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400))) DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
assert_equal true, DateTime.civil(2005,2,10,20,30,44).past? assert_equal true, DateTime.civil(2005,2,10,20,30,44).past?
......
...@@ -7,7 +7,7 @@ def test_to_s_from_dates ...@@ -7,7 +7,7 @@ def test_to_s_from_dates
end end
def test_to_s_from_times def test_to_s_from_times
date_range = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30) date_range = Time.new(2005, 12, 10, 15, 30)..Time.new(2005, 12, 10, 17, 30)
assert_equal "BETWEEN '2005-12-10 15:30:00' AND '2005-12-10 17:30:00'", date_range.to_s(:db) assert_equal "BETWEEN '2005-12-10 15:30:00' AND '2005-12-10 17:30:00'", date_range.to_s(:db)
end end
......
...@@ -457,7 +457,6 @@ def test_to_s ...@@ -457,7 +457,6 @@ def test_to_s
time = Time.utc(2005, 2, 21, 17, 44, 30) time = Time.utc(2005, 2, 21, 17, 44, 30)
assert_equal time.to_default_s, time.to_s assert_equal time.to_default_s, time.to_s
assert_equal time.to_default_s, time.to_s(:doesnt_exist) assert_equal time.to_default_s, time.to_s(:doesnt_exist)
assert_equal "2005-02-21 17:44:30", time.to_s(:db)
assert_equal "21 Feb 17:44", time.to_s(:short) assert_equal "21 Feb 17:44", time.to_s(:short)
assert_equal "17:44", time.to_s(:time) assert_equal "17:44", time.to_s(:time)
assert_equal "February 21, 2005 17:44", time.to_s(:long) assert_equal "February 21, 2005 17:44", time.to_s(:long)
...@@ -469,6 +468,10 @@ def test_to_s ...@@ -469,6 +468,10 @@ def test_to_s
assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822) assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822)
assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822) assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822)
end end
# this one's a special snowflake because the db time is local
time = Time.new(2005, 2, 21, 17, 44, 30)
assert_equal "2005-02-21 17:44:30", time.to_s(:db)
end end
def test_custom_date_format def test_custom_date_format
...@@ -688,7 +691,7 @@ def test_compare_with_time_with_zone ...@@ -688,7 +691,7 @@ def test_compare_with_time_with_zone
def test_minus_with_time_with_zone def test_minus_with_time_with_zone
assert_equal 86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] ) assert_equal 86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
end end
def test_minus_with_datetime def test_minus_with_datetime
assert_equal 86_400.0, Time.utc(2000, 1, 2) - DateTime.civil(2000, 1, 1) assert_equal 86_400.0, Time.utc(2000, 1, 2) - DateTime.civil(2000, 1, 1)
end end
......
...@@ -82,7 +82,8 @@ def test_to_formatted_s ...@@ -82,7 +82,8 @@ def test_to_formatted_s
end end
def test_to_s_db def test_to_s_db
assert_equal '2000-01-01 00:00:00', @twz.to_s(:db) # This test assumes the local timezone of the machine is Pacific.
assert_equal '1999-12-31 16:00:00', @twz.to_s(:db)
end end
def test_xmlschema def test_xmlschema
...@@ -696,7 +697,7 @@ def test_advance_1_year_during_dst ...@@ -696,7 +697,7 @@ def test_advance_1_year_during_dst
assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", twz.years_ago(1).inspect assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", twz.years_ago(1).inspect
assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", (twz - 1.year).inspect assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", (twz - 1.year).inspect
end end
protected protected
def with_env_tz(new_tz = 'US/Eastern') def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz old_tz, ENV['TZ'] = ENV['TZ'], new_tz
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册