Wie konvertiere ich DateTime.now in Ruby in UTC?

96

Wenn d = DateTime.nowja, wie konvertiere ich 'd' in UTC (mit dem entsprechenden Datum)?

Asche
quelle

Antworten:

154

d = DateTime.now.utc

Hoppla!

Das scheint in Rails zu funktionieren, aber nicht in Vanilla Ruby (und das ist natürlich die Frage)

d = Time.now.utc

Funktioniert jedoch.

Gibt es einen Grund, den Sie verwenden müssen DateTimeund nicht Time? Timesollte alles enthalten, was Sie brauchen:

irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009
DanSingerman
quelle
Weil ich das richtige Datum für die Konvertierung haben möchte, dh für GMT +10 kann am nächsten Tag voraus sein ...
Ash
2
Die Zeit wird das für Sie tun. Die Uhrzeit umfasst auch den Datumsteil, nicht nur die Tageszeit. Machen Sie Time.now.inspect, um einen Blick darauf zu werfen.
DanSingerman
2
Oh wie süß. Was ist dann der Unterschied zwischen Datum, Uhrzeit und DateTime?
Asche
18
Die Zeit wird intern als Anzahl von Sekunden und Mikrosekunden seit der Epoche vom 1. Januar 1970 um 00:00 UTC gespeichert. Das Datum wird intern als astronomische julianische Tageszahl dargestellt, und DateTime ist einfach komisch (was wahrscheinlich der Grund ist, warum Rails es überschreibt)
DanSingerman
168
DateTime.now.new_offset(0)

funktioniert in Standard-Ruby (dh ohne ActiveSupport).

Greg Campbell
quelle
3
Und dies ist tatsächlich die richtigste Antwort auf die Frage.
Ernest
2
Dies sollte mehr positive Stimmen haben. DateTime unterscheidet sich von Time. Ich brauchte genau das.
d11wtq
1
new_offsetDas Standardargument ist 0bereits. So DateTime.now.new_offsetkönnen auch verwendet werden.
Cryptor
8

Leider verfügt die DateTime-Klasse nicht über die in der Time-Klasse verfügbaren praktischen Methoden, um dies zu tun. Sie können jedes DateTime-Objekt folgendermaßen in UTC konvertieren:

d = DateTime.now
d.new_offset(Rational(0, 24))

Sie können von UTC zu Ortszeit zurückkehren, indem Sie:

d.new_offset(DateTime.now.offset)

Wo dist ein DateTime-Objekt in UTC-Zeit? Wenn Sie diese als praktische Methoden möchten, können Sie sie folgendermaßen erstellen:

class DateTime
  def localtime
    new_offset(DateTime.now.offset)
  end

  def utc
    new_offset(Rational(0, 24))
  end
end

Sie können dies in der folgenden irb-Sitzung in Aktion sehen:

d = DateTime.now.new_offset(Rational(-4, 24))
 => #<DateTime: 106105391484260677/43200000000,-1/6,2299161> 
1.8.7 :185 > d.to_s
 => "2012-08-03T15:42:48-04:00" 
1.8.7 :186 > d.localtime.to_s
 => "2012-08-03T12:42:48-07:00" 
1.8.7 :187 > d.utc.to_s
 => "2012-08-03T19:42:48+00:00" 

Wie Sie oben sehen können, hat das ursprüngliche DateTime-Objekt einen Offset von -04: 00 (Eastern Time). Ich bin in der pazifischen Zeit mit einem Offset von -07: 00. localtimeWenn Sie wie zuvor beschrieben aufrufen, wird das DateTime-Objekt ordnungsgemäß in die Ortszeit konvertiert. Wenn Sie utcdas Objekt ordnungsgemäß aufrufen, wird es in einen UTC-Offset konvertiert.

Joel Watson
quelle
5

Versuchen Sie dies, funktioniert in Ruby:

DateTime.now.to_time.utc
EEPAN
quelle
4

Sie können eine ENV einstellen, wenn Sie möchten Time.nowund DateTime.nowin UTC-Zeit antworten möchten .

require 'date'
Time.now #=> 2015-11-30 11:37:14 -0800
DateTime.now.to_s #=> "2015-11-30T11:37:25-08:00"
ENV['TZ'] = 'UTC'
Time.now #=> 2015-11-30 19:37:38 +0000
DateTime.now.to_s #=> "2015-11-30T19:37:36+00:00"
jeremywoertink
quelle
2

In irb:

>>d = DateTime.now
=> #<DateTime: 11783702280454271/4800000000,5/12,2299161>
>> "#{d.hour.to_i - d.zone.to_i}:#{d.min}:#{d.sec}"
=> "11:16:41"

konvertiert die Zeit in utc. Aber wie geschrieben, wenn es nur Zeit ist, können Sie verwenden:

Time.now.utc

und sofort bekommen.

Nitecoder
quelle
1

Die Zeichenfolgendarstellung einer DateTime kann von der Time-Klasse analysiert werden.

> Time.parse(DateTime.now.to_s).utc
=> 2015-10-06 14:53:51 UTC
John C.
quelle