Posts Tagged ‘UTC’

Rails: store dates in UTC and display them in local time onto client side

Понедельник, Июнь 27th, 2011

In the Rails all timestamps stored in database in UTC by default. UTC is an improved version of wide-known GMT.

Previously, I have kept the timezone for each individual user for computing local date using UTC and user timezone. Well, you know, when you are asked to specify your timezone, choosen it from a huge drop-down list. Some developers, of course, make smarter, they determine the current user’s timezone with javascript and then send it to the server via AJAX.

Now I come to the conclusion that in most cases I do not necessarily user’s timezone to know (I can’t think where it may be necessary to me.) I decided that will be easier to display all the dates on my site in UTC, then on the client side bring them to local time and format using javascript. As a result, I got a helper and a piece of code in javascript.

Here is rails helper, without any frills:

def utc_date(date)
  raw %Q(<time class="utc-date" title="#{date}">#{date}</time>)
end

This helper just display passed date object and display it wrapped by time HTML5 tag.

And here is a javascript code that convert UTC date to local time and format time:

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();

This example is written using mootools framework, but I think similar method like format is also available in your favorite framework. If not - it’s easy to write this method yourself.
The script simply looks for all the containers with the class .utc-date and convert contained date to local time with formatting.

In general, this is a simple way to remove yourself from a headache to support multiple time zones in your application. I’m waiting for comments about where method I described does not work.

Хранение дат в UTC, отображение и форматирование на клиенте

Четверг, Июнь 23rd, 2011

В 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 и приводит содержащуюся в них дату к локальному времени, с форматированием.

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