Как я могу изменить часовой пояс DateTime в Ruby? - PullRequest
24 голосов
/ 17 декабря 2010

Чтение, запись и сериализация дат и времени при сохранении постоянного часового пояса становится раздражающим.Я использую Ruby (и Rails 3.0) и пытаюсь изменить часовой пояс DateTime.(в UTC), но не само время.

Я хочу это:

t = DateTime.now
t.hour
-> 4
t.offset = 0
t.hour
-> 4
t.utc?
-> true

Самое близкое, что я пришел, это, но это не интуитивно понятно.

t = DateTime.now
t.hour
-> 4
t += t.offset
t = t.utc
t.hour
-> 4
t.utc?
-> true

Есть ли лучший способ?

Ответы [ 7 ]

37 голосов
/ 20 декабря 2010

Используя Rails 3, вы ищете DateTime.change ()

dt = DateTime.now
=> Mon, 20 Dec 2010 18:59:43 +0100
dt = dt.change(:offset => "+0000")
=> Mon, 20 Dec 2010 18:59:43 +0000
9 голосов
/ 09 апреля 2011

Использование смещения числа, например «+1000», не будет работать круглый год из-за перехода на летнее время.Оформить заказ ActiveSupport :: TimeZone. Подробнее здесь

8 голосов
/ 17 декабря 2010
d = DateTime.now
puts [ d, d.zone ]
#=> 2010-12-17T13:28:29-07:00
#=> -07:00

d2 = d.new_offset(3.0/24)
puts d2, d2.zone
#=> 2010-12-17T23:28:29+03:00
#=> +03:00

Редактировать : Этот ответ не учитывает информацию, предоставленную комментарием к другому ответу о том, что желаемое, чтобы сообщаемые «часы» были такими же после изменения часового пояса.

8 голосов
/ 17 декабря 2010

Я бы вместо этого использовал объект Время .Так что получите текущее местное время, затем увеличьте его на смещение UTC и преобразуйте в UTC, например, так:

t = Time.now # or Time.parse(myDateTime.asctime)
t # => Thu Dec 16 21:07:48 -0800 2010
(t + t.utc_offset).utc # => Thu Dec 16 21:07:48 UTC 2010

Хотя, согласно комментарию Phrogz, если вы просто хотите сохранить метки времени независимо от местоположения, то простоиспользовать текущее время UTC:

Time.now.utc
5 голосов
/ 11 января 2017

Как указывало @ Сэм , изменение смещения недостаточно и может привести к ошибкам.Для того, чтобы быть устойчивым к продвижению часов DST, преобразование должно быть сделано следующим образом:

d = datetime_to_alter_time_zone
time_zone = 'Alaska'

DateTime.new
  .in_time_zone(time_zone)
  .change(year: d.year, month: d.month, day: d.day, hour: d.hour, min: d.min, sec: d.sec)
1 голос
/ 27 февраля 2017

Если кто-то (например, я) имеет часовой пояс в строковом формате, например "Pacific Time (США и Канада)"

Чем это лучший способ, который я нашел:

datetime.change(ActiveSupport::TimeZone[time_zone_string].formatted_offset(false)
0 голосов
/ 27 февраля 2017

Вы можете указать часовой пояс, который хотите использовать в своем приложении, добавив следующую строку в файле конфигурации (config / application.rb): config.time_zone = 'Mumbai'

Вы можете найтиофициальная документация для этого же здесь: http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

Другой вариант заключается в том, что вы «Monkey Patch» класс «DateTime».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...