ActiveRecord parse string to datetime?

2020-06-03 01:25发布

If I pass a String into Datetime column while creating new AR object, it will be automatically parse:

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>

How does Rails, or ActiveRecord, do this magic? Which method does it use?

4条回答
劫难
2楼-- · 2020-06-03 01:37

As other comments and the documentation suggests, String#to_datetime "Converts a string to a DateTime value.":

"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
查看更多
狗以群分
3楼-- · 2020-06-03 01:44

Rails adds a to_date method to String. Its source is simple:

# 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 is native to Ruby (the same method is called by Date.parse) and it's where the real work is done.

It first uses a regular expression to remove extraneous symbols from the string, then passes it to other methods like _parse_eu, _parse_iso, _parse_dot and so on. Each of these uses its own regular expressions and other methods to see if it's a date that it understands and extract the meaningful information from it. Once one of them "works" (i.e. returns true), the rest are skipped. Finally, back in _parse, the extracted information is used to build a date and time, doing a little more work to figure out things like checking for the day of the week and whether a year value of "12" should mean 1912 or 2012.

The docs call this a heuristic method, which could be taken to mean it throws a bunch of possibilities at the wall to see what sticks. It's pretty poorly-documented but works remarkably well.

查看更多
对你真心纯属浪费
4楼-- · 2020-06-03 01:45

There's also to_datetime if you need the time.

查看更多
欢心
5楼-- · 2020-06-03 01:46

You probably want to use Date.strptime(str).

查看更多
登录 后发表回答