Работа с тем, как MongoDB хранит DateTime при использовании с шаблоном локатора службы - PullRequest
2 голосов
/ 09 декабря 2011

Мой коллега и я находимся в тупике в дискуссии, и мы будем благодарны за участие других.

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

Проблема, которую мы обсуждаем, возникает, когда у нас есть поля DateTime для объекта и сохраняем его в источнике данных MongoDB.

Что я заметил, так это то, что когда у нас есть объект в C # с DateTime, он отображается как правильное время. Когда мы заходим на наш сервер MongoDB с MongoVUE для проверки объекта, он показывает правильное время. Но когда мы получаем объект, DateTime теперь находится в UTC. Это, очевидно, создает проблемы при сравнении DateTime в памяти с датой в объекте, который был извлечен из источника данных MongoDB.

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

Вот где начинаются дебаты.

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

То, что я прочитал еще, где мы должны хранить наше время в виде строки, в частности, в качестве некоторого стандарта формата UTC. Таким образом, интерфейсный слой не знает и не заботится о том, как хранится DateTime, и не делает наш объект, так как каждый источник данных будет хранить эту строку одинаково.

Мне удалось сделать это с использованием формата ISO 1806, но мой коллега считает, что это «хакерское» исправление и что использование .toLocalTime является подходящим способом справиться с этой ситуацией.

Мне интересно, что другие скажут по теме.

Заранее благодарим вас за ваш вклад.

1 Ответ

8 голосов
/ 09 декабря 2011

Почему вы не храните UTC в БД?В большинстве случаев DateTime следует хранить в UTC, поскольку обычно оно относится к моменту времени.Это верно для всего, что относится ко времени в физическом смысле, и ко всему, что предполагает, что время является монотонным, растущим и уникальным, ни одно из которых не является истинным для большинства локальных времен.

Иногда использование местного времени действительно приводит ксмысл: предположим, что автобус отправляется каждый день в 9 утра.Это означает, что между двумя последовательными событиями проходит 24 часа.Однако, если для часового пояса установлено летнее время, то это будет 23-часовой, соответственно 25-часовой интервал один раз в год.

Однако, если вам необходимо обработать данные такого типа, простой DateTime не подходиттрюк;Правила DST могут изменяться, часовые пояса могут изменяться и т. Д. В C # применяются правила DST, которые действительны в настоящее время , даже если дата является «исторической».Таким образом, арифметика дат с историческими датами может нанести ущерб.Если вам действительно нужно справиться с этим, по крайней мере, вы должны сохранить , в котором часовой пояс, в котором находится время (не только смещение или даже просто флаг isLocal).

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

Кстати, для выполнения второго вы можете украсить свойство с помощью [BsonDateTimeOptions(Kind=DateTimeKind.Local)], который сделает преобразование для вас, но, конечно, страдает от тех же проблем.

...