Комментарии 17
Если я правильно понимаю, осовная фича timestamptz заключается в том, что значение автоматически сохраняется в UTC в соответствии с текущим часовым поясом, и при запросах соответственно преобразуется обратно?
Предположим, мы говорим не о базе, которая работает в рамках одного единственного часового пояса, а паралельно с пользователями из разных часовых поясов.
Не лучше-ли сохранять в базе UTC и делать преобразования ближе к front-end-у?
Мне кажется, тогда можно кешировать больше данных, так как на уровне базы данных и бизнес-логики можно работать в UTC, с однородными данными.
Предположим, мы говорим не о базе, которая работает в рамках одного единственного часового пояса, а паралельно с пользователями из разных часовых поясов.
Не лучше-ли сохранять в базе UTC и делать преобразования ближе к front-end-у?
Мне кажется, тогда можно кешировать больше данных, так как на уровне базы данных и бизнес-логики можно работать в UTC, с однородными данными.
+1
Да, в целом правильно, при условии что вы, принимая пользовательский input, явно указываете, в каком часовом поясе приняли время пользователя, опираясь на его настройки или определяя местоположение по IP, например. Иначе входное время будет некорректно интерпретироваться при конвертации.
Лично я склонен согласиться, что в такой ситуации UTC наиболее эффективен и устраняет много ненужных проблем. Но требуется аккуратность с вводом/выводом значений времени.
Более «ленивый» путь — это четко декларировать что ваш сервис / платформа работают по такому-то времени (будь-то Москва, UTC или что-то иное), и что все операции ввода/вывода времени происходят в этой таймзоне. Это складывает ответственность по учету времени на пользователя, но облегчает разработку и эксплуатацию системы.
Я встречал на практике разные примеры, вопрос в том, что бизнес-задача позволяет. Какой-нибудь серьезный финансовый инструмент практически наверняка должен уметь адекватно работать в условиях пользователей из широкого спектра часовых поясов.
Возможно, коллеги предложат сценарии, когда использование UTC в качестве основной настройки сервера СУБД нежелательно.
Лично я склонен согласиться, что в такой ситуации UTC наиболее эффективен и устраняет много ненужных проблем. Но требуется аккуратность с вводом/выводом значений времени.
Более «ленивый» путь — это четко декларировать что ваш сервис / платформа работают по такому-то времени (будь-то Москва, UTC или что-то иное), и что все операции ввода/вывода времени происходят в этой таймзоне. Это складывает ответственность по учету времени на пользователя, но облегчает разработку и эксплуатацию системы.
Я встречал на практике разные примеры, вопрос в том, что бизнес-задача позволяет. Какой-нибудь серьезный финансовый инструмент практически наверняка должен уметь адекватно работать в условиях пользователей из широкого спектра часовых поясов.
Возможно, коллеги предложат сценарии, когда использование UTC в качестве основной настройки сервера СУБД нежелательно.
0
>Возможно, коллеги предложат сценарии, когда использование UTC в качестве основной настройки сервера СУБД нежелательно.
Я сходу не вспомню адрес, но тут же на Хабре была большая статья, затрагивающая эту проблему.
Суть в том, что для того, чтобы получить время в какой-то локальной временной зоне, надо иметь базу данных по смещению времени в прошлом и в будущем (!) на весь диапазон рассматриваемых времён. Как в UTC записать дату «через 6 месяцев в 10 часов МСК», если неизвестно, какое будет тогда смещение? Поэтому, в принципе, настройка самого сервера к этой проблеме отношения не имеет, это полезно только в смысле анализа логов. А время хранить в полях с временной зоной timestamp with time zone.
>И timestamp, и timestamptz (и другие виды данных, относящиеся ко времени) могут иметь дополнительную точность (“precision”).
Я нарвался на таких незнаек однажды, производители софта для рисования структуры базы, так что надо действительно обращать внимание.
Я сходу не вспомню адрес, но тут же на Хабре была большая статья, затрагивающая эту проблему.
Суть в том, что для того, чтобы получить время в какой-то локальной временной зоне, надо иметь базу данных по смещению времени в прошлом и в будущем (!) на весь диапазон рассматриваемых времён. Как в UTC записать дату «через 6 месяцев в 10 часов МСК», если неизвестно, какое будет тогда смещение? Поэтому, в принципе, настройка самого сервера к этой проблеме отношения не имеет, это полезно только в смысле анализа логов. А время хранить в полях с временной зоной timestamp with time zone.
>И timestamp, и timestamptz (и другие виды данных, относящиеся ко времени) могут иметь дополнительную точность (“precision”).
Я нарвался на таких незнаек однажды, производители софта для рисования структуры базы, так что надо действительно обращать внимание.
0
Я сходу не вспомню адрес, но тут же на Хабре была большая статья, затрагивающая эту проблему.
Про эту говорите? habrahabr.ru/company/mailru/blog/242645
+1
> Суть в том, что для того, чтобы получить время в какой-то локальной временной зоне, надо иметь базу данных по смещению времени в прошлом и в будущем (!) на весь диапазон рассматриваемых времён. Как в UTC записать дату «через 6 месяцев в 10 часов МСК», если неизвестно, какое будет тогда смещение?
Иметь базу на будущее — в принципе невозможно. Мы же не можем предсказать, решит наше правительство осуществлять переход на зимнее/летнее время или нет. Нужный брать требуемый timestamptz at time zone и записывать, в приложении отображать at time zone «Europe/Moscow» и своевременно обновлять базы часовых поясов при внесении в них изменений.
Иметь базу на будущее — в принципе невозможно. Мы же не можем предсказать, решит наше правительство осуществлять переход на зимнее/летнее время или нет. Нужный брать требуемый timestamptz at time zone и записывать, в приложении отображать at time zone «Europe/Moscow» и своевременно обновлять базы часовых поясов при внесении в них изменений.
0
Вот я и пишу — сохранять время в timestampz, как Вы рекомендуете, надо с большой осторожностью.
>Короче говоря, старайтесь избегать timestamp и используйте timestamptz.
Короче говоря, старайтесь избегать timestamp и timestamptz и используйте timestamp with time zone.
Крайний случай — когда ещё надо сохранять дополнительную информацию, а именно смещение так, как его считает правильнымм источник данных. Например, ДНР/ЛНР как часть украины имели одну временную зону, а как отдельное от Украины образование — другую. Основной принцип — не должна происходить потеря исходных данных.
>Короче говоря, старайтесь избегать timestamp и используйте timestamptz.
Короче говоря, старайтесь избегать timestamp и timestamptz и используйте timestamp with time zone.
Крайний случай — когда ещё надо сохранять дополнительную информацию, а именно смещение так, как его считает правильнымм источник данных. Например, ДНР/ЛНР как часть украины имели одну временную зону, а как отдельное от Украины образование — другую. Основной принцип — не должна происходить потеря исходных данных.
0
Всё ж таки не хватает типа, в котором будет храниться кроме таймстампа ещё и часовая зона: и идентификатор и смещение. Для хранения времён в будущем это важно, чтобы ловить непредсказуемые изменения часовых зон.
0
Это палка о двух концах. Возможно, я не понимаю сценарий, когда необходимо хранить время в заведомо неправильной, относительно текущей действительности, таймзоне. Но в такой ситуации, если вы запишите уйму меток в формате «timestamp +03», например (для Московского времени), потом депутаты решат сделать перевод таймзоны, и у вас будет большая проблема с кучей таймстампов, не соответствующих действительности. Дело дойдет либо до усложнения бизнес-логики (вручную в приложении разруливать такие ситуации), либо до внесения изменений в БД для корректировки часового пояса. Я такие приключения наблюдал в крупном продакшене, это очень печально.
0
Я так понимаю, товарищ говорил о том, чтобы вместе с временем сохранять ID часового пояса (типа 1='America/Los_Angeles')
Тогда время может быть корректно рассчитано даже при изменении зимнего/летнего времени или часовых поясов.
Тогда время может быть корректно рассчитано даже при изменении зимнего/летнего времени или часовых поясов.
0
И все равно проблема есть. Если у нас сохранено. «2010-01-01 15.00.00» utc и отдельно сохранено таймзона = 'Moskow' Что это нам дает?? Проблемы, учитывая, что в то время смещение Москвы от utc было не такое как сейчас!!!
0
Почему не такое?
Расчет смещения по конкретному часовому поясу для исторических данных будет всегда возвращать одинаковое локальное время для исторических дат, не взирая на решения текущего правительства по смене зимнего/летнего времени или даже смене часового пояса для конкретной местности — все изменения будут касаться только будущих дат.
Как правильно заметили выше, будущие даты возможно придется корректировать, особенно если в данной местности сменили сам часовой пояс. Но не прошлые даты (за крайне редким исключением баг фиксов в исторических часовых поясах — я видел пару таких случаев, вроде-бы).
Расчет смещения по конкретному часовому поясу для исторических данных будет всегда возвращать одинаковое локальное время для исторических дат, не взирая на решения текущего правительства по смене зимнего/летнего времени или даже смене часового пояса для конкретной местности — все изменения будут касаться только будущих дат.
Как правильно заметили выше, будущие даты возможно придется корректировать, особенно если в данной местности сменили сам часовой пояс. Но не прошлые даты (за крайне редким исключением баг фиксов в исторических часовых поясах — я видел пару таких случаев, вроде-бы).
0
У меня есть случай, когда время указывается с временной зоной «местное время». Вот где настоящий ад. Поэтому с указанием времени приходится хранить информацию об источнике времени.
0
Сценарий таков: сохраняем тройку значений: корректное время в будущем в UTC, оно же локальное (или смещение, не суть), идентификатор часовой зоны. Потом наша госдума доблестно переводит всю нашу страну (или часть) на час или два в какую-то сторону и перекраивает часть часовых поясов. Задача: после обновления tzdata найти те времена, которые «поехали» и исправить. Для каких-то таймстампов надо перемотать локальное время, для каких-то — время в UTC (если нам важно сохранить именно значение локального времени). Собственно, задача уже рассматривалась в этой статье, которую уже процитировали и тут и на фейсбуке: habrahabr.ru/company/mailru/blog/242645 и решение про тройку значений взято оттуда.
+1
Мы храним все даты в UTC, конвертируем вводные и выходные данные. Но есть вариант, когда надо работать с временными зонами на уровне самой базы — отчеты. Например график количества заказов по дням недели — границы дней недели зависит от временной зоны клиента.
Пока мы не кешируем статистику, но когда будем это делать, к ключу кеша надо будет добавлять временную зону клиента.
Пока мы не кешируем статистику, но когда будем это делать, к ключу кеша надо будет добавлять временную зону клиента.
0
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Как работать с метками времени (timestamp) в PostgreSQL?