В Rails по-умолчанию все даты в БД хранятся в UTC. UTC - это, можно сказать, улучшенная версия знакомого всем GMT.
Раньше я хранил часовой пояс для каждого отдельного пользователя, чтобы потом считать локальную дату, основываясь на UTC и временной зоне пользователя, которую он указал. Ну, вы знаете, когда вас просят указать ваш часовой пояс, выбрав нужный из огромного выпадающего списка. Некоторые разработчики, конечно, делают умнее, они определяют текущий часовой пояс пользователя или посетителя при помощи javascript и отправляют его на сервер при помощи AJAX.
Теперь же я пришел к выводу, что мне вообще не обязательно, в большинстве случаев, знать часовой пояс пользователя (навскидку не могу придумать, где это может мне понадобиться). Я подумал, что проще все даты на сайте выводить в UTC формате, затем на клиенте приводить их к локальному времени и форматировать при помощи javascript. В результате, я получил один хелпер и один кусочек кода на javascript.
Вот хелпер. Он пока что без особых изысков:
def utc_date(date)
raw %Q(<time class="utc-date" title="#{date}">#{date}</time>)
end
Этот хелпер просто получает объект даты в UTC формате и выводит его в HTML5 теге time (я использую HTML5 в своих проектах).
А вот и кусок джаваскрипта, который приводит дату к локальной, а так же форматирует её:
var Application = {
processUtcDates: function() {
$$('.utc-date').each(function(wrapper) {
wrapper.set('html', Application.utcToLocal(wrapper.get('html')))
})
},
utcToLocal: function(value) {
var a = /^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})\sUTC$/.exec(value);
if (a) {
return (new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]))).format("%d/%m/%Y %H:%M");
}
return null;
}
};
Application.processUtcDates();
Этот пример javascript-кода написан с использованием фреймворка mootools, но я думаю, аналог метода format есть и в вашем любимом фреймворке. Если же нет - его легко написать самому.
Скрипт просто ищет все контейнеры с классом .utc-date и приводит содержащуюся в них дату к локальному времени, с форматированием.
В общем, вот таким простым способом можно снять с себя головную боль по поддержке разных часовых поясов в вашем приложении. Жду комментариев о том, где описанный мною способ не подходит.
Also interesting
Tags: javascript, mootools, rails, UTC
не могу представить необходимость выводить дату в UTC и показать пользователю в его таймзоне.
сразу выводить в таймзоне пользователя стандартными средстами
> сразу выводить в таймзоне пользователя стандартными средстами
Каким образом? Вот я, например, из Екатеринбурга, и у меня локальное время 14:00, а вы, к примеру, из Москвы и у вас еще 12:00. Я пишу комментарий и если при добавлении комментария указывается моё локальное время, то вы увидите мой комментарий из будущего (для вас).
А когда указывается время в UTC, то на клиенте все рассчитается правильно при помощи JS (конечно, в том случае, если в вашей ОС правильно выставлено время и временная зона).
> пока будем делать простые вещи сложными и придумывать бизнес-правила для
> отображения контента, будем стоять на месте с пустыми карманами
Это простые в общем-то вещи. Я думаю, что учитывать подобные “мелочи” - признак внимания к своим пользователям.
не встречал подобный функционал, но только сейчас понял, насколько это может быть удобно.
действительно, многие парятся из-за разницы часовых поясов
You make my day =)
пока будем делать простые вещи сложными и придумывать бизнес-правила для отображения контента, будем стоять на месте с пустыми карманами
Вот еще есть вариант:
в cookies устанавливаю время пользователя:
function set_time_zone_offset() {
var current_time = new Date();
$.cookie(’time_zone’, current_time.getTimezoneOffset());
};
set_time_zone_offset()
а в application.rb в before_filter прописываю:
def set_time_zone
min = request.cookies["time_zone"].to_i
Time.zone = ActiveSupport::TimeZone[min.minutes]
end
Вроде работает.
Действительно простое и безгеморойное решение!