2008-12-09 6 views
30

Rails' ActiveSupport module extends the builtin ruby Time class with a number of methods.Rails ActiveSupport Zeitanalyse?

Bemerkenswert ist, gibt es die to_formatted_s Methode, die Sie eine Zeichenfolge in Datenbank-Format zu erhalten, schreiben Time.now.to_formatted_s(:db) lässt, anstatt überall hässliche strftime Format-Strings zu schreiben.

Meine Frage ist, gibt es eine Möglichkeit, rückwärts zu gehen?

So etwas wie Time.parse_formatted_s(:db), die eine Zeichenfolge im Datenbankformat analysieren und ein neues Time-Objekt zurückgeben würde. Das scheint etwas zu sein, das Schienen bieten sollten, aber wenn es ist, kann ich es nicht finden.

Kann ich es nicht finden, oder muss ich es selbst schreiben?

Dank

Antwort

55

Es ist wie Active sieht die Parsing-Methoden bereitstellt, die Sie suchen (und ich wurde zu suchen), nachdem alle! — zumindest wenn die Zeichenfolge, die Sie analysieren möchten, ein Standardformat ist, ISO-8601-formatiert().

Wenn das zu analysierende Datum bereits in Ihrer lokalen Zeitzone ist, ist es wirklich einfach!

> 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 

und zeitzonen bewusst Zeit kann dann leicht

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

oder zu anderen Zeitzonen zu UTC umgewandelt werden:

> 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 

Wenn die Datumszeichenfolge Sie versuchen, zu analysieren ist in UTC, auf der anderen Seite sieht es nicht aus wie es gibt eine Methode, es direkt in eine TimeWithZone zu analysieren, aber ich konnte umgehen, dass zuerst mit Da teTime.strptime ...

Wenn das Datum Sie versuchen, ist in UTC zu analysieren und Sie wollen es als UTC bleiben, können Sie verwenden:

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

Wenn das Datum Sie versuchen, Parse ist in UTC und Sie wollen es zu einem Standard-Zeitzone umgewandelt, können Sie verwenden:

> 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 

es sieht aus wie es auch andere Formate analysieren kann, wie das seltsame Format, das Time # to_s produziert:

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" 

Ich bin ziemlich beeindruckt.

Hier sind einige weitere Beispiele aus [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 

Weitere Dokumentation Links Referenz:

+0

Danke für das Posten so viel Detail. Ihre DateTime.strptime() - Referenz ist sehr nützlich für den Fall, in dem ich ein Datum aus der Datenbank analysieren muss, das ActiveRecord :: Base.connection.select_value() als String zurückgibt. – Lee

+0

Killerantwort. Ich habe nicht bemerkt, dass Time.zone = "..." funktioniert hat. Du hast mich gerade eine Menge Zeit gerettet. – rhh

+2

Danke für die Antwort! Wenn Sie die globale TZ nicht ändern möchten, können Sie Time :: use_zone verwenden, z. Verwenden Sie zum Parsen von UTC Time.use_zone ('UTC') {Time.zone.parse '2012-11-01 13:37'}. – Divide

1
>> "2009-09-24".to_date 
=> Thu, 24 Sep 2009 
>> "9/24/2009".to_date 
=> Thu, 24 Sep 2009 

Funktioniert gut, es sei denn, Ihr Datum ist in einem seltsamen Format.

+0

"etwas seltsames Format" - wie ein Datum formatiert wie der Rest der Welt tut es? :) –

5
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08') 
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00 
2

Ich bin gerade auch reingelaufen und keine der obigen Antworten war zufriedenstellend für mich. Idealerweise könnte man ActiveSupport::TimeZone genauso wie Time verwenden und .strptime darauf mit einem beliebigen Format aufrufen und das korrekte TimeZone Objekt zurückbekommen. ActiveSupport::TimeZone.strptime existiert nicht so habe ich diese 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 
3

Rails 5 schließlich bietet 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 
Verwandte Themen