Come posso convertire DateTime.now in UTC in Ruby?


96

In caso affermativo d = DateTime.now, come faccio a convertire "d" in UTC (con la data appropriata)?

Risposte:


154

d = DateTime.now.utc

Ops!

Sembra funzionare in Rails, ma non vanilla Ruby (e ovviamente questo è ciò che si pone la domanda)

d = Time.now.utc

Funziona comunque.

C'è qualche motivo per cui devi usare DateTimee non Time? Timedovrebbe includere tutto ciò di cui hai bisogno:

irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009

Perché voglio la data corretta per la conversione, cioè, per GMT +10 può essere avanti il ​​giorno successivo ...
Ash

2
Il tempo lo farà per te benissimo. L'ora include anche la parte della data, non solo l'ora del giorno. Fai Time.now.inspect per dare un'occhiata.
DanSingerman,

2
Che dolce. Allora qual è la differenza tra Date, Time e DateTime?
Ash

18
Il tempo viene memorizzato internamente come numero di secondi e microsecondi dall'epoca, 1 gennaio 1970, 00:00 UTC. La data, internamente, è rappresentata come un numero del giorno giuliano astronomico e DateTime è semplicemente strana (che è probabilmente il motivo per cui Rails la sostituisce)
DanSingerman

168
DateTime.now.new_offset(0)

funzionerà in Ruby standard (cioè senza ActiveSupport).


3
E questa è in realtà la risposta più corretta alla domanda.
Ernest

2
Questo dovrebbe avere più voti positivi. DateTime è diverso da Time. Avevo proprio bisogno di questo.
d11wtq

1
new_offsetil valore predefinito dell'argomento del metodo è 0già. Quindi DateTime.now.new_offsetpuò essere utilizzato anche.
Cryptor

8

Sfortunatamente, la classe DateTime non dispone dei metodi convenienti disponibili nella classe Time per eseguire questa operazione. Puoi convertire qualsiasi oggetto DateTime in UTC in questo modo:

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

Puoi tornare da UTC a ora locale utilizzando:

d.new_offset(DateTime.now.offset)

dove dè un oggetto DateTime nell'ora UTC. Se desideri questi metodi di convenienza, puoi crearli in questo modo:

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

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

Puoi vederlo in azione nella seguente sessione irb:

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" 

Come puoi vedere sopra, l'oggetto DateTime iniziale ha un offset di -04: 00 (Eastern Time). Sono nel fuso orario del Pacifico con un offset di -07: 00. La chiamata localtimecome descritto in precedenza converte correttamente l'oggetto DateTime nell'ora locale. La chiamata utcsull'oggetto lo converte correttamente in un offset UTC.


5

Prova questo, funziona in Ruby :

DateTime.now.to_time.utc

4

È possibile impostare un ENV se si desidera che Time.nowe DateTime.nowrisponda nell'ora UTC.

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"

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"

convertirà l'ora nell'utc. Ma come pubblicato se è solo Tempo puoi usare:

Time.now.utc

e ottenerlo subito.


1

La rappresentazione di stringa di un DateTime può essere analizzata dalla classe Time.

> Time.parse(DateTime.now.to_s).utc
=> 2015-10-06 14:53:51 UTC
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.