Добро пожаловать в одну из самых сложных проблем некомпьютерного программирования - правильное представление даты и времени для конечных пользователей.
Реально, временные метки должны храниться в фиксированном единственном представлении независимо от того, как они будут интерпретироваться, потому что как бы вы ни старались, у вас всегда будут неоднозначные случаи, и вы не сможете разрешить их без фиксированного представления. И вы выбрали один из худших вариантов использования - планирование встречи. Единственный наиболее распространенный вариант использования - это авиаперелет, когда поездка может начинаться в одном часовом поясе и заканчиваться в другом, возможно в более раннее местное время.
Всегда, всегда ВСЕГДА сохраняйте в UTC и отображайте в предпочтительном или явно указанном часовом поясе пользователя. Если это вообще возможно, заставьте пользователя сообщать вам, в каком часовом поясе, по его мнению, находится временная метка при вводе ( например , иметь явное поле часового пояса и предварительно заполнить его предпочитаемой зоной).
Самый простой способ работы с информацией о дате / времени зависит от требований вашего приложения.
Если дата и время вводятся пользователем, а сервер не обрабатывает эту информацию о дате / времени, кроме как для ее сохранения в базе данных, и не ожидается, что введенное время будет адаптировано к месту, где оно просматривается (например, , пользователь ввел «8:00 PM», и он должен отображаться как «8:00 PM» независимо от того, где в мире он просматривается), тогда самый простой способ - сохранить DateTime как местное время без какой-либо информации о часовом поясе.
С другой стороны, если сервер должен использовать введенный DateTime в качестве триггера, чтобы сделать что-то, или если время должно быть правильно настроено на текущий часовой пояс, тогда лучше всего сохранить DateTime как время UTC и настроить его на местное время. время (для текущего местоположения пользователя) каждый раз, когда вы читаете его из базы данных.
источник
Важно, чтобы вы не связывали два взаимосвязанных понятия.
Если вы манипулируете фактическим моментом времени, то есть конкретным временем определенного дня, то единственный способ сделать это - всегда использовать универсальное значение времени UTC. Никогда не пытайтесь сохранить это как значение, относящееся к часовому поясу. При отображении этого значения времени для пользователя всегда выполняйте преобразование в часовой пояс пользователя в это время. (И не забудьте, что время и дата зависят от часового пояса.)
Другая концепция - это выражение времени, такое как «8:00 вечера каждый вторник». Вы упомянули, что людям разрешено назначать встречи, и если у вас есть повторяющиеся встречи, вам нужно такое выражение. Я не знаю ни одного стандартного языка выражений, но что бы вы ни использовали, он будет зависеть от часового пояса человека, который его указал. Было бы лучше сделать это прямо, например, «8:00 вечера каждый вторник в тихоокеанском часовом поясе». В случае выражения времени вы всегда сохраняете это как строку и никогда не используете форматы системного времени.
Смотрите больше обсуждений этого в моем блоге
источник
Многие ответы здесь указывают на хранение как UTC. Но будь очень осторожен с этим. Например, если вы запланируете встречу на 12:00, но встреча состоится после перехода на летнее время, что произойдет? UTC не хранит никакой информации о том, была ли функция dst активной во время сохранения встречи. Многие крупные известные системы допустили эту ошибку, когда пользователь отправляет электронное письмо летом в 9:00, а зимой отправленное время показывает 8:00, потому что вычисление обратно из UTC зависит от того, когда вы посмотрите на дату и время, не в тот момент, когда дата была записана.
Гораздо лучше предположить, что ваш пользователь хочет иметь время, которое он выбрал всегда. Без преобразования UTC, без преобразования времени, без информации о часовом поясе, ничего. Назначить встречу с 08:00 до 12:00 21 марта 2016 года - это как раз то, что нужно. Не используйте ни местное время, ни время UTC, но укажите неопределенное время (в json это не имеет ни z, ни +, в основном, в .NET это DateTime.Kind = DateTimeKind.Unspecified).
Конечно, если ваш вариант использования заключается в том, что вы являетесь компанией, которая проводит встречи с кем-то из разных часовых поясов, и вы хотите видеть эту информацию, скажем, в календаре компании, но позволить пользователям видеть, какое время находится в их часовом поясе, это становится все сложнее. Время должно быть правильным для разных людей в разных часовых поясах (поставщик и заказчик).
В этих случаях вы можете даже захотеть записать, когда встреча была сохранена в базе данных, в каком часовом поясе и включала ли она dst или нет. Таким образом, вы всегда можете рассчитать обратно местное время на что-либо еще, либо на то, что будет сейчас, либо на то, что предполагалось исторически. Потому что часовые пояса очень не статичны, что еще более усложняет ситуацию.
К счастью, именно здесь приходят такие библиотеки, как http://nodatime.org/, и мы настоятельно рекомендуем это сделать. Они работают с датами гораздо более последовательно. Даже тогда я бы порекомендовал обернуть все ваши переменные даты и логику в ваши собственные обертки, используя интерфейсы, чтобы их можно было смоделировать, и тогда вы все равно сможете переключать логику позже.
источник