Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

  • подход на стороне сервера
  • подход на стороне клиента

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

Предполагая, что значение, которое вы хотите отобразить, поступает из базы данных: 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