Конвертировать UTC в точное время по Rails 3

У меня возникли проблемы с преобразованием UTC Time или TimeWithZone в локальное время в Rails 3.

Скажите moment - это некоторая переменная Time в формате UTC (например, moment = Time.now.utc). Как преобразовать moment в мой часовой пояс, заботясь о DST (т.е. Используя EST/EDT)?

Точнее, я хотел бы распечатать "Понедельник, 14 марта, 9 утра", если время соответствует сегодняшнему утру 9 утра EDT и "Понедельник 7 марта 9:00", если время было 9 утра EST в последний понедельник.

Надеюсь, есть другой способ?

Изменить: Сначала я подумал, что "EDT" должен быть признанным часовым поясом, но "EDT" не является фактическим часовым поясом, больше как состояние часового пояса. Например, не было бы смысла спрашивать Time.utc(2011,1,1).in_time_zone("EDT"). Это немного запутанно, так как "EST" - это фактический часовой пояс, используемый в нескольких местах, которые не используют летнее время и являются (UTC-5) в течение года.

Ответ 1

У Rails есть свои имена. См. Их с помощью:

rake time:zones:us

Вы также можете запустить rake time:zones:all для всех часовых поясов. Чтобы увидеть больше задач, связанных с зоной: rake -D time

Итак, чтобы преобразовать в EST, автоматически обслуживать DST:

Time.now.in_time_zone("Eastern Time (US & Canada)")

Ответ 2

Time#localtime предоставит вам время в текущем часовом поясе машины, на которой запущен код:

> moment = Time.now.utc
  => 2011-03-14 15:15:58 UTC 
> moment.localtime
  => 2011-03-14 08:15:58 -0700 

Обновление. Если вы хотите перейти на определенные часовые пояса, а не на свой часовой пояс, вы на правильном пути. Однако, вместо того, чтобы беспокоиться о EST против EDT, просто перейдите в общую зону Восточного времени - он будет знать, основываясь на дне, будь то EDT или EST:

> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
  => Mon, 14 Mar 2011 11:21:05 EDT -04:00 
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
  => Sat, 14 Jan 2012 10:21:18 EST -05:00 

Ответ 3

На самом деле есть хороший Gem, называемый local_time by basecamp, чтобы делать все это только на стороне клиента. Я полагаю:

https://github.com/basecamp/local_time

Ответ 4

Легко настроить его, используя локальную зону вашей системы, Просто в своем приложении .rb добавьте это

config.time_zone = Time.now.zone

Затем рельсы должны показывать вам временные метки по местному времени или вы можете использовать что-то вроде этой инструкции, чтобы получить местное время

Post.created_at.localtime

Ответ 5

Не знаю, почему, но в моем случае это не работает так, как было предложено ранее. Но он работает следующим образом:

Time.now.change(offset: "-3000")

Конечно, вам нужно изменить значение offset на ваш.