Правильное хранение дат с TimeZone в БД MySQL для приложения Rails - PullRequest
5 голосов
/ 01 июня 2009

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

У меня есть эти настройки в environment.rb:

config.active_record.default_timezone = :utc
config.time_zone = "UTC"

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

Time.zone = user.time_zone

Где user.time_zone - это выбранное ими предпочтение (например, US Pacific Time).

Это прекрасно работает в приложении, но мой вопрос касается того, что Rails затем сохраняет в БД MySQL. Если пользователь выбирает дату 1 июня 2009 года, она сохраняется в поле DATETIME в базе данных в формате UTC, но с смещением часового пояса. Например, если пользователь выбрал часовой пояс GMT+6, выбранная дата 1 июня 2009 года попадает в базу данных как 2009-06-01 06:00:00 UTC.

Я ожидал, что это будет храниться как 2009-06-01 00:00:00 UTC в базе данных. Правильно ли мое мышление или Rails делает здесь что-то неожиданное?

Ответы [ 3 ]

4 голосов
/ 03 июня 2009

В этом блоге рассказывается об обработке часовых поясов в Rails 2.1 +:

http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/

Суть в том, что Rails будет хранить все записи в БД в формате UTC, а затем конвертировать в часовой пояс пользователя для отображения. Что имеет смысл: сохранить все данные в нейтральной форме, а затем преобразовать их в нужную форму в последнюю минуту.

1 голос
/ 03 июня 2009

Исходя из вашего ответа на мой комментарий, я бы сказал, просто сохранить дату на основе времени локального сервера, а затем использовать JavaScript Date :: toLocaleString (), чтобы преобразовать ее в свой местный часовой пояс. Я написал статью об этом пару лет назад, которую вы можете найти здесь .

JS статьи был написан на MooTools, но с тех пор я переписал его с помощью jQuery, поэтому я покажу этот код.

Важные части:

При рендеринге в HTML используйте миллисекунды с начала эпохи.

<span class="dt"><!-- <%= blah.created_at_epoch_ms %> --><%= blah.created_at %></span>

Для чего требуется метод в вашей модели, определенный следующим образом:

def created_at_epoch_ms
    self.created_at.to_i * 1000
end

JS для преобразования дат:

$(document).ready(function(){
        $('span.dt').each(function(){
                var date = new Date();

                date.setTime(this.firstChild.data);

                $(this).parent().text(date.toLocaleString());
        });
});

Это должно преобразовать строку в местное время пользователя, и волшебство происходит в toLocaleString (). Единственный браузер, о котором я слышал, не реализует его, это Safari 2.0, который не должен вызывать особых проблем, так как я думаю, что большинство пользователей пошли дальше.

Я использую этот метод на моем сайте , и если вы посмотрите на исходный код страницы, вы увидите, что он делает. Фактический код, отправляемый в браузер, выглядит следующим образом:

<!-- 1243484521000 -->2009-05-28 04:22:01 UTC

Что конвертируется в моем браузере (центральное время) в

Wednesday, May 27, 2009 11:22:01 PM

Если у них включен JS, он примет значение узла комментария, преобразует его и заменит всю строку (включая время UTC) местным временем. Если JS отключен, они просто увидят время так, как его видит сервер.

0 голосов
/ 01 июня 2009

Вам необходимо установить часовой пояс в объекте данных, прежде чем устанавливать дату.

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