Rails 3 to_s(:db) when database time is NOT UTC

about ActiveRecord’s default_timezone setting.
rails31>> Time.now.to_s(:db)
=> "2011-09-23 03:02:52"
rails31>> 1.second.ago.to_s(:db)
=> "2011-09-23 10:02:59"

WHAT??? I know that these are 2 different classes:

rails31>> Time.now.class
=> Time
rails31>> 1.second.ago.class
=> ActiveSupport::TimeWithZone

This is because ActiveSupport sets to UTC before doing the “to_s” which makes sense with the default Rails configuration where all dates are stored in the DB as UTC.

https://github.com/rails/rails/blob/master/activesupport/lib/active_support/time_with_zone.rb

# :db format outputs time in UTC; all others output time in local.
# Uses TimeWithZone's +strftime+, so %Z and %z work correctly.
def to_s(format = :default)
  if format == :db
    utc.to_s(format)
  elsif formatter = ::Time::DATE_FORMATS[format]
    formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
  else
    "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
  end
end
alias_method :to_formatted_s, :to_s

I guess I understand this because I’m dealing with 2 different libraries: ActiveRecord vs ActiveSupport, but it sure threw me for a loop in some of my tests where I would sometimes create values with Time.now and other times with 1.day.ago and the time-zone conversion would fail the test.

My solution to this issue is to start using .to_s(:localdb) rather than .to_s(:db)

Time::DATE_FORMATS.merge!(:localdb=>"%Y-%m-%d %H:%M:%S")
或者设置  config.time_zone = 'Central Time (US & Canada)'
或者不要调用to_s 系统默认的就是需要的时间   通过设置 Time::DATE_FORMATS[:default] = "%Y-%m-%d %H:%M:%S"
 rails2:
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.update(:default => '%Y/%m/%d')
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.update(:default => '%Y/%m/%d %H:%M')

 

你可能感兴趣的:(Date,timezone,database,Rails,ActiveRecord,output)