Как отображать время в часовом поясе пользователя

Я использую rails 3.0.5, и я создал_at и updated_at, хранящиеся в UTC. Теперь я хочу отобразить время created_at в часовом поясе пользователя. Я считаю, что можно выбрать часовой пояс пользователя из браузера, а затем преобразовать время в часовой пояс пользователя.

Я уверен, что у рельсов будет gem / plugin, чтобы позаботиться о чем-то подобном. Есть что-то?

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

Чтобы преобразовать даты в часовой пояс вашего пользователя, у вас есть в основном две возможности:

  1. серверный подход
  2. подход на стороне клиента

Подход на стороне сервера

Если ваш сайт разрешает регистрацию, вы можете сохранить часовой пояс пользователя в качестве предпочтения пользователя. В таблице пользователя сохраните часовой пояс пользователя. Затем создайте настраиваемый помощник, который вы можете использовать для форматирования любой даты / времени в соответствующий часовой пояс, используя метод in_time_zone .

 > t = Time.current # => Mon, 23 Dec 2013 18:25:55 UTC +00:00 > t.zone # => "UTC" > t.in_time_zone("CET") # => Mon, 23 Dec 2013 19:25:55 CET +01:00 

Ваш помощник может выглядеть так:

 def format_time(time, timezone) time.in_time_zone(timezone) end 

Я обычно также хочу выводить стандартный формат, используя помощник I18n.l

 def format_time(time, timezone) I18n.l time.to_time.in_time_zone(timezone), format: :long end 

Клиентский подход

Если на вашем сайте нет регистрации или вы не хотите запрашивать у своих пользователей свой часовой пояс или просто хотите использовать часовой пояс пользовательской системы, вы можете использовать JavaScript.

Мое предложение состоит в том, чтобы создать пользовательский помощник, который будет распечатываться каждый раз надлежащим образом, чтобы вы могли создать общую функцию JavaScript для преобразования значений.

 def format_time(time, timezone) time = time.to_time content_tag(:span, I18n.l(time, format: :long), data: { timezone: timezone, time: time.iso8601 }) end 

Теперь создайте функцию JavaScript, выполняемую при загрузке DOM, и выберете все tags HTML с атрибутом data-time . Скопируйте их и обновите значение внутри тега span с соответствующим временем в заданном часовом поясе.

Простым примером jQuery будет

 $(function() { $("span[data-time]").each(function() { // get the value from data-time and format according to data-timezone // write the content back into the span tag }); }); 

Я не размещаю полный код здесь, так как есть много форматов времени JavaScript, доступных с простым поиском. Вот несколько возможных решений

  • Преобразование даты в другой часовой пояс в JavaScript
  • Преобразование даты в локальный часовой пояс с помощью javascript

Хорошая жемчужина от Basecamp называется local_time для рендеринга на стороне клиента – https://github.com/basecamp/local_time . Это отлично подходит для приложений, в которых пользователь не подключен, и он кэшируется.

Вы можете добавить это в свой прикладной controller для преобразования всех времен в часовой пояс пользователя:

 class ApplicationController < ActionController::Base around_filter :user_time_zone, :if => :current_user def user_time_zone(&block) Time.use_zone(current_user.timezone_name, &block) end end 

Вам просто нужно зафиксировать часовой пояс пользователя

Предполагая, что значение, которое вы хотите отобразить, поступает из базы данных: ie started_at и является (по умолчанию), хранящимся в UTC.

Если у вас есть часовой пояс пользователя в качестве смещения, вы также можете локализовать время, выполнив следующие действия:

 started_at.in_time_zone(-2) => Mon, 24 Feb 2014 23:07:56 GST -02:00 

Который тогда можно размахивать всякими способами, чтобы получить нужные вам детали:

 started_at.in_time_zone(-2).yesterday => Sun, 23 Feb 2014 23:07:56 GST -02:00 started_at.in_time_zone(-2) + 3.days => Thu, 27 Feb 2014 23:07:56 GST -02:00 

http://api.rubyonrails.org/classes/Time.html#method-c-use_zone

Это то, что вы ищете:

 Time.use_zone(@user.timezone) do blah blah blah end 

Возможно, вам захочется взглянуть на эти ссылки в дополнение к одному из них:

  • Rails 3 SSL Устаревание
  • Создание отношений много-много в Rails
  • Создание строки таблицы в ссылке в Rails
  • Поймать все исключения в controllerе рельсов
  • Rails: ссылки «Next post» и «Previous post» в моем представлении, как?
  • Как изменить порт по умолчанию сервера Rails 3 в развитии?
  • net :: ERR_INCOMPLETE_CHUNKED_ENCODING только в Chrome
  • Переопределение Rails default_scope
  • rails server bin / rails: 6: предупреждение: уже инициализированная постоянная ошибка APP_PATH
  • has_and_belongs_to_many vs has_many через
  • Добавление lib в 'config.autoload_paths' в Rails 3 не выполняет автозагрузку моего модуля
  • Давайте будем гением компьютера.