Подтвердить что ты не робот

ActiveRecord анализирует строку в datetime?

Если я передаю столбец String в Datetime при создании нового объекта 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>

Как делает Rails или ActiveRecord эту магию? Какой метод он использует?

4b9b3361

Ответ 1

Rails добавляет метод to_date к String. Его источник прост:

# 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), а где выполняется реальная работа.

Сначала он использует регулярное выражение для удаления посторонних символов из строки, затем передает его другим методам, например _parse_eu, _parse_iso, _parse_dot и так далее. Каждый из них использует свои собственные регулярные выражения и другие методы, чтобы определить, соответствует ли она дате, которую она понимает, и извлекать из нее значимую информацию. Когда один из них "работает" (т.е. Возвращает true), остальные пропускаются. Наконец, в _parse, извлеченная информация используется для создания даты и времени, делая немного больше работы, чтобы выяснить, что такое проверка на день недели и значение года "12" должно означать 1912 или 2012.

Документы называют это эвристическим методом, который можно понимать как означающее, что он бросает кучу возможностей на стену, чтобы увидеть, какие палки. Это довольно плохо документировано, но работает замечательно.

Ответ 2

Вероятно, вы хотите использовать Date.strptime(str).

Ответ 3

Там также to_datetime, если вам нужно время.

Ответ 4

Как и другие комментарии и документация, 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