使用rails将日期字符串转换为数据库时使用的格式

时间:2011-02-03 12:34:58

标签: ruby-on-rails date

我的用户想要使用日期格式%d /%m /%Y(例如:26/02/2011)。

为了正确显示日期,我因此改为:environment.rb中的默认格式:

environment.rb :

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
     :default => "%d/%m/%Y"
)

它工作正常,但在尝试将以此格式输入的日期字符串保存在数据库中时遇到一个问题。

Rails似乎采用%m /%d /%Y而不是%d /%m /%Y形成的字符串 04/02/2011保存为2011-04-02,26/02/2011完全无效,未保存......

我为此搜索了解决方案,但我找到的依赖于重新格式化模型中的日期,如下所示:

mymodel.rb :   

def datefield_formatted
   datefield.strftime '%m/%d/%Y'
end

def datefield_formatted=(value)
   self.datefield = Time.parse(value)
end


view.html.erb :

<%= form.input :datefield_formatted %>

我可以使用此解决方案但是我需要更改每个'datefield'的模型(我的应用程序中有很多)。

因此我想知道是否有人告诉Rails在转换并保存到数据库时正确地'读'字符串为%d /%m /%Y.

2 个答案:

答案 0 :(得分:1)

我认为最好的方法是以通常的sql格式保存日期(即日期字段不是varchar),只显示在%d /%m /%Y中。 为此,我通常使用本地化文件和l(日期)功能。 例如 这在本地化文件中

date:
  formats:
    default: "%d/%m/%Y"

以及在视图中使用日期的任何地方 l(date)

另一个想法是重载activerecord如何保存日期,但这有点过分:/

答案 1 :(得分:1)

我最终找到了一个更深入地搜索Stackoverlow的解决方案:

此博客文章解释了该问题,并提供了一个有效的解决方案: http://blog.nominet.org.uk/tech/2007/06/14/date-and-time-formating-issues-in-ruby-on-rails/

所以我们有: lib / column-patch.rb

class ActiveRecord::ConnectionAdapters::Column

def self.string_to_date(string)
    return string unless string.is_a?(String)

    begin
        return DateTime.strptime(string, ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default])
    rescue
        date_array = ParseDate.parsedate(string)
        # treat 0000-00-00 as nil
        Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
    end
end

def self.string_to_time(string)
    return string unless string.is_a?(String)

    begin
    if dt=Date._strptime(string,ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[:default])
        return Time.mktime(*dt.values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday))
    else
        raise "Bad format"
    end
    rescue
        time_hash = Date._parse(string)
        time_hash[:sec_fraction] = microseconds(time_hash)
        time_array = time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)
        # treat 0000-00-00 00:00:00 as nil
        Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue DateTime.new(*time_array[0..5]) rescue nil
    end
end

end

我们添加 config / environment.rb

require 'column-patch'