Преобразование UTC в местное время в Rails 3

95

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

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

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

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

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

Марк-Андре Лафортюн
источник

Ответы:

113

У Rails есть свои названия. Смотрите их с:

rake time:zones:us

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

Итак, чтобы преобразовать в EST, автоматически перейдя на DST:

Time.now.in_time_zone("Eastern Time (US & Canada)")
Забба
источник
21
Как вы могли бы автоматически использовать часовой пояс для пользователя, открывающего веб-приложение?
dmonopoly
Я нашел единственный способ - использовать Javascript и затем передать его на сервер. (new Date()).getTimeZoneOffset(). Но это довольно непоследовательно, так что этот парень, кажется, написал свое собственное: onlineaspect.com/2007/06/08/…
Герцог
2
автоматически добавить часовой пояс ко всем датам времени ActiveRecord - config.time_zone = 'Eastern Time (US & Canada)' - в config / application.rb
idrinkpabst
Обновление: владелец связанного JS-решения указывает на более новое решение: pellepim.bitbucket.org/jstz
Майлз,
@dmonopoly, вы можете установить часовой пояс в конфигурации приложения, config.time_zone = 'Wellington'а затем использовать Time.current (который эквивалентен time.now, но использует установленный вами часовой пояс)
Шон
116

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 
Дилан Маркоу
источник
Это начало. Как установить текущий часовой пояс (поскольку я даже не уверен, где будет размещено приложение, сервер может находиться в другом часовом поясе, чем тот, который следует использовать).
Marc-André Lafortune
6
Метод «localtime» хорош, но часовой пояс компьютера, на котором выполняется код, не так полезен, как часовой пояс пользователя, обращающегося к веб-приложению. (Как уже упоминалось здесь: stackoverflow.com/questions/6003491/rails-3-user-timezones/… ) Как можно узнать часовой пояс для пользователя, обращающегося к веб-приложению?
dmonopoly
@daze Я полагаю, вы могли бы настроить для своих пользователей возможность выбора своих часовых поясов, а затем использовать этот in_time_zoneметод с их часовым поясом .
Дилан Маркоу
1
Спасибо, метод localtime - именно то, что мне нужно.
Боб
Time.now.localtimeработает в обычном сеансе irb, но когда я пытаюсь запустить его на компьютере, который находится в часовом поясе UTC, он не работает.
Ava
15

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

config.time_zone = Time.now.zone

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

Post.created_at.localtime
jacr1614
источник
15

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

https://github.com/basecamp/local_time

Махатманих
источник
Это работает лучше всего. Мы знаем, что время уже сохранено, способ показать его в формате пользователю, по моему мнению, лучше всего делать на стороне клиента, и это делает это.
Neeraj Shukla
1

Не знаю почему, но в моем случае это не работает так, как предлагалось ранее. Но работает это так:

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

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

Сейбо Гло
источник
0

Если вы на самом деле делаете это только потому, что хотите получить часовой пояс пользователя, тогда все, что вам нужно сделать, это изменить свой часовой пояс в себе config/applications.rb.

Как это:

Rails по умолчанию сохранит вашу запись времени в формате UTC, даже если вы укажете текущий часовой пояс.

config.time_zone = "Singapore"

Так что это все, что вам нужно сделать, и все готово.

Aladrain
источник