Как отобразить время в часовом поясе пользователя - PullRequest
38 голосов
/ 11 марта 2011

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

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

Ответы [ 7 ]

52 голосов
/ 23 декабря 2013

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 helper

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, доступных с простым поиском.Вот несколько возможных решений

15 голосов
/ 06 марта 2015

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

6 голосов
/ 24 декабря 2013

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

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

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

3 голосов
/ 10 мая 2014

Предполагая, что отображаемое вами значение исходит из базы данных, то есть 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
1 голос
/ 01 октября 2018

Если вы хотите преобразовать дату в определенный часовой пояс:

deadline.in_time_zone(time_zone)

Здесь крайний срок - дата.

Кроме того, вы можете найти Универсальное время через местный компьютер Часовой пояс плюс местное время и наоборот, как в Карачи - +05: 00, вы можете просто добавить его к значению в Универсальном времени, чтобы найти время в вашем часовом поясе или получите универсальное время из вашего местного времени, вычитая разницу часовых поясов (в нашем случае 05:00) из вашего местного времени

1 голос
/ 08 июня 2012

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

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

Time.use_zone(@user.timezone) do
  blah blah blah
end
0 голосов
/ 11 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...