Всегда ли рекомендуется хранить время в формате UTC или в этом случае лучше хранить время в местном масштабе?

Как правило, рекомендуется хранить время в формате UTC, как указано в здесь и здесь.

Предположим, есть повторяющееся событие, скажем, время окончания, которое всегда в одно и то же местное время, скажем 17:00, независимо от того, включено или выключено летнее время для этого часового пояса. Также существует требование не изменять время вручную, когда летнее время включается или выключается для определенного часового пояса. Также требуется, чтобы всякий раз, когда время окончания запрашивается любыми другими системами через API (например, GetEndTimeByEvent), он всегда отправляет время окончания в формате UTC.

Подход 1. Если принято решение сохранить в UTC, его можно сохранить в таблице базы данных, как показано ниже.

Event      UTCEndTime
=====================
ABC         07:00:00
MNO         06:00:00
PQR         04:00:00

Для первого события ABC время окончания по всемирному координированному времени - 07:00, что при преобразовании для отображения из всемирного координированного времени в местное время 1 июля 2012 года приведет к 17:00 по местному времени, а если оно будет преобразовано 10 октября 2012 года ( дата, когда для часового пояса установлено летнее время), то результатом будет 18:00, что не является правильным временем окончания.

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

Подход 2. Однако, если оно сохранено как местное время, как показано ниже, например, для события ABC, оно всегда будет 17:00 в любой день, поскольку преобразование в из UTC по местному времени.

Event      LocalEndTime
=======================
ABC         17:00:00
MNO         16:00:00
PQR         14:00:00

А уровень приложения преобразует местное время во время UTC для отправки в другие системы через (API GetEndTimeByEvent).

Можно ли в этом случае сохранить время в формате UTC? Если да, то как установить постоянное местное время?

Связанные вопросы: Is есть ли веская причина хранить время не в формате UTC?


person Sun    schedule 18.07.2012    source источник
comment
Будет ли программа использоваться только для такого рода мероприятий? Нужно ли будет обслуживать события, происходящие во время перехода на летнее время? Должна ли программа обрабатывать изменение часовых поясов?   -  person Michał Górny    schedule 20.07.2012
comment
@Michal Да, все события всегда происходят по местному времени (например, 16:00 или 21:00 и т. Д.) Определенного местного часового пояса, независимо от того, включено или выключено летнее время. Допустим, конкретное событие MNO происходит в Лондоне в 16:00 по местному времени каждый день независимо от того, включено или выключено летнее время.   -  person Sun    schedule 21.07.2012


Ответы (6)


Я думаю, что для ответа на этот вопрос мы должны подумать о преимуществах использования UTC для хранения временных меток.

Я лично считаю, что главное преимущество этого заключается в том, что время всегда (в основном) гарантированно согласовано. Другими словами, всякий раз, когда меняется часовой пояс или применяется летнее время, вы не перемещаетесь назад или вперед во времени. Это особенно полезно для файловых систем, журналов и так далее. Но это необходимо в вашем приложении?

Подумайте о двух вещах. Во-первых, о времени перехода часов на летнее время. Вероятно ли, что ваши события будут происходить между 2 и 3 часами ночи (в тот день, когда закончится сдвиг часов)? Что тогда должно произойти?

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

Если вы ответили нет на оба этих вопроса, то вам лучше использовать местное время. Это упростит ваше приложение. Но если вы хотя бы раз ответили да, думаю, вам стоит подумать еще раз.


И это все о базе данных. Другой момент - это формат времени, используемый внутри приложения, и он должен зависеть от того, что вы на самом деле будете делать с этим временем.

Вы упомянули, что показываете время через API. Будет ли приложение запрашивать базу данных при каждом запросе? Если вы храните время внутри как UTC, вам нужно будет либо это сделать, либо иным образом убедиться, что при изменении летнего времени / часового пояса кэшированное время будет скорректировано / сокращено.

Будет ли оно что-нибудь делать с самим временем? Например, распечатать событие произойдет через 8 часов или приостановить себя примерно на это время? Если да, то вероятно UTC будет лучше. Конечно, нужно продумать все вышеперечисленные вопросы.

person Michał Górny    schedule 21.07.2012
comment
Итак, если я сохраню DateTime как UTC DateTime (а не как varchar, ToUniversalTime c #) в базе данных, то при заполнении мне всегда нужно преобразовывать его на стороне клиента, чтобы получить точную дату? - person AhammadaliPK; 02.04.2020

Мне нравится думать об этом так:

Компьютеры не заботятся о времени как о понятном человеку представлении. Их не волнуют часовые пояса, форматирование строки даты и времени или что-то еще. Только люди заботятся о том, как интерпретировать и представлять время.

Позвольте базе данных делать то, в чем она хороша: хранить время в виде числа - либо эпоху UNIX (количество секунд, прошедших с 01.01.1970), либо метку времени UTC (без информации о часовом поясе или летнем времени). Заботьтесь о представлении времени в понятной человеку форме только тогда, когда это необходимо. Это означает, что в логике вашего приложения, системе отчетности, консольном приложении или любом другом месте данные будут просматриваться человеком.

person NathanAldenSr    schedule 19.12.2013
comment
Проблема в том, что вы не можете перейти от значений даты и времени ни к эпохе, ни к всемирному координированному времени назад к исходной дате / времени местного часового пояса пользователя (без сохранения дополнительной информации). Преобразование из местного часового пояса в эпоху или всемирное координированное время является преобразованием с потерями. - person Peter; 16.08.2017
comment
Трудно ответить 600 символами, поэтому я рекомендую вам продолжить чтение. Этот вопрос SO является хорошим началом и содержит множество ссылок для дальнейшего чтения: stackoverflow.com/questions/2532729/ - person Peter; 15.12.2017
comment
Центральное значение имеет понимание предметной области и того, содержит ли она физическое время, гражданское время или и то, и другое. Epoch подходит для обработки физического времени (хотя я предпочитаю UTC), но для систем, над которыми я работал, гражданское время обычно гораздо более распространено. - person Peter; 15.12.2017
comment
Потери могут произойти при прохождении через представления с плавающей запятой. Например, longs, содержащие x-Since epoch, являются отличным способом хранения временных меток, за исключением JavaScript, где нет longs, потому что, ну, JavaScript. Усечение часового пояса также может произойти, когда вы проходите время, которое я и вне часового пояса знают и не знают (глядя на вас, драйверы Python sql) - person user48956; 08.02.2018

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

Сохранение в формате UTC - это нормально, но есть одно требование, которое вызывает боль, если вы это делаете: «Можете ли вы написать мне отчет, который покажет мне, сколько X происходит в день?»

Если вы храните даты в формате UTC, это требование вызовет боль; вам необходимо написать код настройки часового пояса на сервере приложений и в вашей отчетности; Это необходимо учитывать при каждом специальном запросе, который вы выполняете к данным, которые включают критерии даты.

Если ваше заявление соответствует следующим критериям:

  1. Каждый экземпляр находится в одном часовом поясе.
  2. Переходы между часовыми поясами обычно происходят в нерабочее время, или вы действительно не заботитесь о «продолжительности» вещей до того уровня, когда пропущенный час или около того будет иметь значение.

Я предлагаю вам сохранить datetime как местное время, используя библиотеку, которая изолирует вас от проблем с конфигурацией часового пояса сервера (например, Noda.Time в мире .net).

person Gumzle    schedule 10.04.2016
comment
Я думаю, что вы правы, но я обнаружил, что ваш тон голоса меня немного отвлекает. Думаю, ваш ответ был бы более ценным, если бы вы написали его более нейтрально / формально :). - person Zero3; 19.01.2017

Если ваши межсистемные сообщения используют ISO 8601, а ваша база данных хранит местное время происхождения + смещение (например, datetimeoffset в MSSQL или ISODate в Mongo, поскольку ISO 8601 фиксирует его), и вы используете только DateTimeOffset в .NET или OffsetDateTime в Java или какой-либо эквивалент в вашем коде, тогда никаких преобразований не требуется. Вы просто храните это. Все функции сравнения будут работать.

Если вы конвертируете в UTC в своей настойчивости, вы теряете смещение с точки зрения пользователя. Отображение того, когда ваш пользователь подписал документ десять лет назад, теперь является сложной проблемой. Вычисление этого из UTC будет означать поиск правил DST, которые действовали в то время на этой территории. Кошмарный сон.

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

person Luke Puplett    schedule 20.04.2017
comment
Есть ли ресурсы, которыми можно поделиться по этому поводу? - person prasanthv; 12.10.2017
comment
Использование временных меток не в формате UTC имеет несколько проблем, их слишком много, чтобы перечислить в комментариях, но я добавлю несколько ссылок в конце. Если вам нужен часовой пояс отметки времени, вы можете сохранить его в дополнительном комментарии. Тогда вы получите все преимущества UTC, сохранив при этом возможность преобразовать временную метку в метку, которая фиксирует все исходные данные. - 2018.javazone.no/program/0507d823-bfa9-483c-8aef -3881c38c315e - ideas.kentico.com/forums/239189-kentico-product-ideas/ - person oligofren; 03.10.2018
comment
Джон Скит написал сегодня сообщение по этой теме. codeblog.jonskeet.uk/2019 / 03/27 / - person Luke Puplett; 27.03.2019
comment
Конвертация в UTC ничего не теряет с точки зрения пользователя. Вы можете преобразовать UTC в любой часовой пояс, но вы не можете все часовые пояса в UTC. Вот почему UTC является стандартом и поэтому называется Univeral. Некоторые идут дальше и всегда сохраняют оба формата времени на случай, если что-то пошло не так (указан неправильный часовой пояс). - person jgmjgm; 01.04.2019

Я бы просто сохранил компонент Time без какой-либо зоны. Каждый раз, когда API должен его обслуживать, добавьте правильную дату и преобразуйте ее как местное время в UTC для этой даты.

База данных = 17:00 (используйте метку времени без даты, часы в байтах, минуты в байтах, строка)

Получить = Дата, где мы хотим событие + База данных 17:00 => Преобразовать это из локального в UTC

Таким образом, вы всегда будете показывать правильное время по всемирному координированному времени.

person IvoTops    schedule 20.07.2012
comment
А как насчет событий, которые происходят в дни перехода на летнее время в часы перехода? У меня есть данные, которые произошли 13 марта между часом ночи или двумя часами ночи. Я получал сообщение об ошибке, когда пытался преобразовать его в UTC, и я не знаю, учитывались ли временные метки переключателем или нет. - person trench; 21.06.2016

На самом деле вы не сохраняете конкретный момент времени, как предполагает большинство API времени. Используйте интервалы, если ваша база данных поддерживает это (PostgreSQL поддерживает), или сохраните их как целое число, представляющее количество секунд (минут / часов) с полуночи или соответствующего начала расписания (понедельник, первое число месяца и т. Д.). В любом случае вы избавились от многих головных болей, связанных с беспокойством о том, как «время» обрабатывается между системами, и добавили лишь очень незначительную головную боль, связанную с преобразованием секунд во время дня в вашем представлении.

person Rich Remer    schedule 21.07.2015