Рельсы ActiveSupport Время Синтаксический?

голоса
30

ActiveSupport модуль Rails' расширяет предопределённый класс рубина времени с целым рядом методов.

В частности, существует to_formatted_sметод, который позволяет писать , Time.now.to_formatted_s(:db)чтобы получить строку в формате базы данных, вместо того , чтобы писать уродливые strftimeформат-строки везде.

Мой вопрос, есть ли способ, чтобы идти в обратном направлении?

Нечто подобное , Time.parse_formatted_s(:db)которые бы разобрать строку в формате базы данных, возвращая новый объект Time. Это похоже на то , что рельсы должны предоставлять, но если она есть, я не могу найти его.

Могу ли я просто не в состоянии найти его, или мне нужно написать это сам?

благодаря

Задан 10/12/2008 в 00:52
источник пользователем
На других языках...                            


5 ответов

голоса
55

Похоже , ActiveSupport действительно обеспечивает методы синтаксического анализа , которые вы ищете (и я искал тоже), в конце концов! - по крайней мере , если строка , которую вы пытаетесь разобрать является стандартом, ISO-8601 в формате ( :dbформат) дата.

Если дата вы пытаетесь разобрать уже в вашем часовом поясе, это очень легко!

 > Time.zone.parse('2009-09-24 08:28:43')
=> Thu, 24 Sep 2009 08:28:43 PDT -07:00

 > Time.zone.parse('2009-09-24 08:28:43').class
=> ActiveSupport::TimeWithZone

и что время часового пояса, известно, может затем легко быть преобразовано в UTC

 > Time.zone.parse('2009-09-24 08:28:43').utc
=> 2009-09-24 15:28:43 UTC

или других часовых поясов:

 > ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona", "Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern Time (US & Canada)", "Indiana (East)"]

 > Time.zone.parse('2009-09-24 08:28:43').utc.in_time_zone('Eastern Time (US & Canada)')
=> Thu, 24 Sep 2009 11:28:43 EDT -04:00

Если строка даты вы пытаетесь разобрать в UTC, с другой стороны, это не выглядит как есть любой способ , чтобы разобрать его непосредственно в TimeWithZone, но я был в состоянии работать вокруг этого быть первым использованием DateTime.strptime ...

Если дата вы пытаетесь разобрать в UTC, и вы хотите, чтобы остаться в UTC, вы можете использовать:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time
=> 2009-09-24 08:28:43 UTC

Если дата вы пытаетесь разобрать в UTC, и вы хотите преобразовать в вашей временной зоне по умолчанию, вы можете использовать:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time.in_time_zone
=> Thu, 24 Sep 2009 01:28:43 PDT -07:00

Похоже, что это может даже разобрать другие форматы, такие как странный формат, который производит Time # to_s:

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08').to_s(:db)
    => "2009-09-23 09:18:08"

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08 EDT').to_s(:db)
    => "2009-09-23 06:18:08"

Я очень впечатлен.

Вот еще несколько примеров из [ http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html][1] :

  Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00

Больше документации Ссылки для справки:

Ответил 24/09/2009 в 22:24
источник пользователем

голоса
5
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00
Ответил 05/08/2010 в 17:17
источник пользователем

голоса
3

Рельсы 5 , наконец , обеспечивает strptime!

value = '1999-12-31 14:00:00'
format = '%Y-%m-%d %H:%M:%S'
Time.zone.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 HST -10:00

ActiveSupport::TimeZone.all.sample.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 GST +04:00
Ответил 07/02/2016 в 06:36
источник пользователем

голоса
2

Я просто побежал в это , а также и ни один из вышеуказанных ответов не были удовлетворительными для меня. В идеале можно было бы использовать ActiveSupport::TimeZoneтак же , как Timeи позвонить .strptimeна него с любой произвольной форме и получить обратно правильный TimeZoneобъект. ActiveSupport::TimeZone.strptimeне существует , так что я создал этот monkeypatch:

 class ActiveSupport::TimeZone
    def strptime(str, fmt, now = self.now)
      date_parts = Date._strptime(str, fmt)
      return if date_parts.blank?
      time = Time.strptime(str, fmt, now) rescue DateTime.strptime(str, fmt, now)
      if date_parts[:offset].nil?
        ActiveSupport::TimeWithZone.new(nil, self, time)
      else
        time.in_time_zone(self)
      end
    end
  end
Ответил 17/05/2012 в 23:37
источник пользователем

голоса
1
>> "2009-09-24".to_date
=> Thu, 24 Sep 2009
>> "9/24/2009".to_date
=> Thu, 24 Sep 2009

Прекрасно работает, если ваша дата не в каком-то странном формате.

Ответил 25/09/2009 в 02:40
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more