Как мне преобразовать DateTime.now в UTC в Ruby?

98

Если да d = DateTime.now, как мне преобразовать d в UTC (с соответствующей датой)?

Ясень
источник

Ответы:

156

d = DateTime.now.utc

Ой!

Кажется, это работает в Rails, но не в ванильном Ruby (и, конечно, это то, что задает вопрос)

d = Time.now.utc

Однако работает.

Есть ли причина, по которой вам нужно использовать, DateTimeа не Time? Timeдолжно включать все необходимое:

irb(main):016:0> Time.now
=> Thu Apr 16 12:40:44 +0100 2009
ДэнЗингерман
источник
Потому что мне нужна правильная дата для преобразования, то есть для GMT +10 может быть впереди на следующий день ...
Эш,
2
Время сделает это за вас. Время также включает дату, а не только время дня. Сделайте Time.now.inspect, чтобы посмотреть.
DanSingerman
2
О сладкий. Так в чем же тогда разница между Date, Time и DateTime?
Эш
18
Время хранится внутри как количество секунд и микросекунд с начала эпохи 1 января 1970 г., 00:00 UTC. Дата внутренне представлена ​​как астрономический номер дня по юлианскому календарю, а DateTime выглядит просто странно (вероятно, поэтому Rails переопределяет его)
Дэн Сингерман,
169
DateTime.now.new_offset(0)

будет работать в стандартном Ruby (т.е. без ActiveSupport).

Грег Кэмпбелл
источник
3
И это, собственно, самый правильный ответ на вопрос.
Эрнест
2
У этого должно быть больше голосов. DateTime отличается от Time. Мне было нужно именно это.
d11wtq
1
new_offsetаргумент метода по умолчанию 0уже. Так DateTime.now.new_offsetтоже можно использовать.
Cryptor
8

К сожалению, класс DateTime не имеет для этого удобных методов, доступных в классе Time. Вы можете преобразовать любой объект DateTime в UTC следующим образом:

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

Вы можете вернуться с UTC на местное время, используя:

d.new_offset(DateTime.now.offset)

где d- объект DateTime по времени UTC. Если вы хотите использовать их в качестве удобных методов, вы можете создать их следующим образом:

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

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

Вы можете увидеть это в действии в следующем сеансе 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" 

Как вы можете видеть выше, исходный объект DateTime имеет смещение -04: 00 (восточное время). Я нахожусь в тихоокеанском времени со смещением -07: 00. Вызов, localtimeкак описано ранее, правильно преобразует объект DateTime в местное время. Вызов utcобъекта правильно преобразует его в смещение UTC.

Джоэл Уотсон
источник
5

Попробуйте это, работает на Ruby :

DateTime.now.to_time.utc
EEPAN
источник
4

Вы можете установить ENV, если хотите, чтобы ваш Time.nowи DateTime.nowотвечал в 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"
Jeremywoertink
источник
2

В 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"

преобразует время в utc. Но, как написано, если это просто время, вы можете использовать:

Time.now.utc

и получите его прямо сейчас.

ниткодер
источник
1

Строковое представление DateTime может быть проанализировано классом Time.

> Time.parse(DateTime.now.to_s).utc
=> 2015-10-06 14:53:51 UTC
Джон С.
источник