2009-06-03 3 views
14

Javascript на моей странице сохраняет клиенту UTC смещение к файлу cookie. Как использовать этот файл cookie для создания TimeZone и назначить его Time.zone?Установить текущий Time.zone в Rails?

мне нужно что-то вроде:

before_filter :set_time_zone 

def set_time_zone 
    Time.zone = ActiveSupport::TimeZone.new('my timezone', cookies[:timezone]) 
end 

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

ответ

14

Вот рабочий гугле ответ:

min = cookies[:timezone].to_i 
Time.zone = ActiveSupport::TimeZone[-min.minutes] 

Просто чтобы понять, то Javascript часть:

if(!($.cookie('timezone'))) { 
    current_time = new Date(); 
    $.cookie('timezone', current_time.getTimezoneOffset(), { path: '/', expires: 10 }); 
} 
+0

Вы также, возможно, потребуется удалить, что >>> если (! ($. печенье ('часовой пояс'))) <<< состояние, как ваши посетители сайта могут путешествия, и там нужно обновить их значение часового пояса. – yek

+1

Одна небольшая проблема: 'TimeZone [-min.minutes]' возвращает первый доступный часовой пояс со смещением 'min.minutes'. Например, для Токио он возвращает Иркутск. Таким образом, этот метод будет работать, если вам не нужно отображать имя часового пояса или код. – arkadiy

+2

@arkadiy прав, но это не только проблема, потому что вы можете получить часовые пояса, которые не соблюдают летнее время (DST). В этом случае результат - неправильное время. Кроме того, 'new Date(). GetTimezoneOffset()' возвращает текущее смещение, включая DST, но выбор 'ActiveSupport :: TimeZone []' ожидает стандартного смещения часового пояса, поэтому вы должны обновить функцию javascript [как это] (http://bit.ly/timezone_js). Вы можете увидеть [эту тему] (https://github.com/potomak/tomatoes/issues/8#issuecomment-2167461) о проблеме, если хотите узнать об этом больше. –

3

Когда я это хранится в моей модели пользователя это так просто, как это

def set_time_zone 
    Time.zone = current_user.time_zone unless current_user.blank? 
end 

поэтому, возможно, вы могли бы сделать

def set_time_zone 
    Time.zone = cookies[:timezone] 
end 

Это проверялось, я никогда не пытался сделать это с cookie, я думаю, что имеет смысл хранить его в модели User.

+0

Нет, мне не нужно хранить его в пользовательской модели. В любом случае, как выглядит ваша current_user.time_zone? Это строка? – snitko

+1

Да, просто используя Rails, созданный в часовом поясе, поэтому для моего пользователя в приложении это будет просто «Сидней» – nitecoder

+0

Как правило, доступ к объектам, таким как сеанс и cookie в модели (M часть MVC), не является хорошей практикой – yek

6

@snitko - ты ответ работал большой для меня в течение длительного времени. Однако, как отметил @Giovanni, в некоторых сценариях не учитывается переход на летнее время, так как он извлекает первый часовой пояс с учетом минутного смещения. Я нашел простой рабочий ответ, который учитывает DST.

Голова здесь - http://site.pageloom.com/automatic-timezone-detection-with-javascript, это детектор времени javascript. Вы просто скопируете код javascript, связанный с веб-сайта (или правой here) в свои файлы javascript вашего приложения (приложение application.js отлично работает). Он позволяет получить часовой пояс через объект с именем jstz.

Тогда в application.html.erb у меня есть

<script type="text/javascript"> 

    var timezone = jstz.determine(); 
    document.cookie = 'time_zone='+timezone.name()+';'; 

</script> 

И в application_controller.rb, у меня есть

before_filter :set_timezone 

private 
def set_timezone 
    Time.zone = cookies["time_zone"] 
end 

И это все, что вам нужно! Часовой пояс установлен правильно для вашего приложения Rails.

EDIT: Возможно, вам необходимо поместить код настройки cookie javascript после тега <\body> в application.html.erb из-за различного способа загрузки и загрузки файлов javascript.

+0

Эй, я знаю его давно ... но я делаю это. Не могли бы вы прояснить последнюю строку? И вам не нужно обновлять страницу после того, как вы установили cookie, чтобы повлиять на текущую страницу? –

+0

Последняя строка устанавливает часовой пояс как глобальную конфигурацию для вашего приложения. Если у вас много людей, которые нажимают ваше приложение из разных часовых поясов, это может быть не лучший подход (по сравнению с настройкой часового пояса для отдельного пользователя). Но да, вы правы, вам нужно обновить страницу, чтобы сервер отображал страницу с обновленным часовым поясом, чтобы увидеть любые связанные с временем изменения. – efatsi

+0

Эй, я считаю, что Time.zone является потокобезопасной, и до тех пор, пока вы устанавливаете ее при каждом запросе, я не думаю, что нужно вмешиваться между запросами? Кроме того, я на самом деле имел в виду вашу EDIT: строка, в которой говорится о размещении файлов cookie в конце? –

Смежные вопросы