Ruby on rails ActiveRecord将字符串解析为datetime?

Ruby on rails ActiveRecord将字符串解析为datetime?,ruby-on-rails,datetime,activerecord,Ruby On Rails,Datetime,Activerecord,如果我在创建新AR对象时将字符串传递到日期时间列中,它将自动解析: 1.9.2p290 :011 > Movie.new(:release_date=>"21-Nov-1990") => #<Movie id: nil, release_date: "1990-11-21 00:00:00", created_at: nil, updated_at: nil> 1.9.2p290:011>新电影(:发行日期=>“1990年11月21日”) => # Rails

如果我在创建新AR对象时将
字符串
传递到
日期时间
列中,它将自动解析:

1.9.2p290 :011 > Movie.new(:release_date=>"21-Nov-1990")
 => #<Movie id: nil, release_date: "1990-11-21 00:00:00", created_at: nil, updated_at: nil>
1.9.2p290:011>新电影(:发行日期=>“1990年11月21日”)
=> #

Rails
,或
ActiveRecord
,是如何实现这一魔力的?它使用哪种方法?

您可能想使用
Date.strtime(str)

Rails向
字符串添加一个方法。其来源很简单:

# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 42
def to_date
  return nil if self.blank?
  ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
end
Date.\u parse
是Ruby固有的(相同的方法由
Date.parse
调用),并且它是

它首先使用正则表达式从字符串中删除无关符号,然后将其传递给其他方法,如
\u parse\u eu
\u parse\u iso
\u parse\u dot
等。每种方法都使用自己的正则表达式和其他方法来查看它是否理解某个日期,并从中提取有意义的信息。一旦其中一个“起作用”(即返回true),其余的将被跳过。最后,在
\u parse
中,提取的信息用于构建日期和时间,做一些更多的工作来确定诸如检查一周中的哪一天以及年份值“12”是指1912年还是2012年


医生们称之为启发式方法,这可能意味着它会在墙上抛出一堆可能性,看看有什么坚持。它的文档记录得很差,但效果非常好。

如果您需要时间,还可以使用
到_datetime

如其他注释和文档所示,“将字符串转换为datetime值。”


strtime
必须知道日期格式,否则将使用默认格式。但是AR可以神奇地解析多种格式的日期。请确保您正在测试用户可能呈现的所有日期格式。它们并不总是确定性的。我还意识到,
Date
列在我向它传递字符串时的行为是相同的。我发现在
rails/activemodel/lib/active\u model/type/date.rb
中有一个
cast\u value(value)
方法(在活动模型中,有许多
cast\u value(value)
方法可以调用
fast\u string\u to\u date(value)
fallback\u string\u to\u date(value)
方法(如果值是string)。我猜在保存记录之前,
cast\u值
会被ActiveModel调用。
"1-1-2012".to_datetime            # => Sun, 01 Jan 2012 00:00:00 +0000 
"01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000 
"2012-12-13 12:50".to_datetime    # => Thu, 13 Dec 2012 12:50:00 +0000 
"12/13/2012".to_datetime          # => ArgumentError: invalid date