Перетворити UTC на місцевий час у Rails 3


95

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

Скажімо, momentце якась Timeзмінна в UTC (наприклад moment = Time.now.utc). Як мені перевести momentсвій часовий пояс, піклуючись про літній час (тобто за допомогою EST / EDT)?

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

Сподіваємось, є інший спосіб?

Редагувати : Я спочатку подумав, що "EDT" повинен бути визнаним часовим поясом, але "EDT" не є фактичним часовим поясом, більше схожим на стан часового поясу. Наприклад, не було б сенсу просити Time.utc(2011,1,1).in_time_zone("EDT"). Це трохи заплутано, оскільки "EST" - це фактичний часовий пояс, який використовується в кількох місцях, де не використовується перехід на літній час і (UTC-5) триває рік.

Відповіді:


113

Рейки мають свої назви. Перегляньте їх за допомогою:

rake time:zones:us

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

Отже, щоб перетворити на EST, автоматично обслуговуючи літній час:

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 = 'Східний час (США та Канада)' - у config / application.rb
idrinkpabst

Оновлення: власник пов'язаного рішення JS вказує на новіше рішення: pellepim.bitbucket.org/jstz
Майлз

@dmonopoly, ви можете встановити часовий пояс у конфігурації програми, config.time_zone = 'Wellington'а потім використовувати Time.current (що еквівалентно time.now, але використовував встановлений вами часовий пояс)
Шон

114

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, це не працює.
Ава

15

Налаштувати його легко за допомогою вашої локальної зони системи, просто додайте це у своєму application.rb

config.time_zone = Time.now.zone

Потім рейки повинні показувати мітки часу у вашому локальному часі, або ви можете скористатися чимось на зразок цієї інструкції, щоб отримати місцевий час

Post.created_at.localtime

15

Насправді є симпатичний самоцвіт, якого закликає local_timebasecamp робити все це лише на стороні клієнта, я вважаю:

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"

Отже, це все, що вам потрібно зробити, і ви готові піти.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.