如果我在创建新AR对象时将String
传递到Datetime
列,它将自动解析:
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>
Rails
或ActiveRecord
如何做到这一点?它使用哪种方法?
答案 0 :(得分:18)
Rails向String
添加to_date
方法。它的来源很简单:
# 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._parse
是Ruby的原生(同样的方法由Date.parse
调用)并且它是where the real work is done。
它首先使用正则表达式从字符串中删除无关符号,然后将其传递给其他方法,如_parse_eu
,_parse_iso
,_parse_dot
等。这些中的每一个都使用自己的正则表达式和其他方法来查看它是否是它理解的日期并从中提取有意义的信息。一旦其中一个“工作”(即返回true),则跳过其余部分。最后,回到_parse
,提取的信息用于建立日期和时间,做一些工作来找出诸如检查星期几以及年份值“12”是否意味着的事情1912年或2012年。
文档称这是一种启发式方法,可以理解为它会在墙上抛出一堆可能性以查看是什么。它的记录很差,但效果非常好。
答案 1 :(得分:2)
如果你需要时间,还有to_datetime
。
答案 2 :(得分:1)
您可能想要使用Date.strptime(str)
。
答案 3 :(得分:0)
正如其他评论和文档所示,String#to_datetime“将字符串转换为DateTime值。”:
"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