Где установить значение datetime UTC в приложении n-уровня: уровень представления, домен или база данных?

Кажется, что это должен быть очевидный вопрос, но у меня были некоторые проблемы, которые нашли хороший ответ. Я создаю приложение n-уровня, которое должно быть чувствительным к времени UTC. Значения могут обновляться, и когда они записываются в метку времени. Это включает транзакции в базе данных, где обновления или вставки будут влиять на столбцы datetime.

Чтобы дать некоторый контекст, я использую SQL 2008 R2 + с DATETIMEOFFSET (2) для большинства моих столбцов datetime. Я рассматриваю возможность добавления обновлений временных меток в Хранимые процедуры, чтобы они не пропускались через сеть. Это позволит сэкономить пропускную способность по мере роста системы, что является хорошей вещью... и может использоваться для проверки того, будут ли изменения данных (сначала выигрыши) в общих данных. Нижняя сторона заключается в том, что первым, кто отправит транзакцию, может быть не тот, кто выигрывает, если они натолкнутся на более медленное время отклика на свой экземпляр приложения.

Каков идеальный или рекомендуемый способ обработки данных времени UTC в этом контексте?

  • Установите его в SPROC с помощью SYSUTCDATETIME() ИЛИ...
  • Установите его в приложении с помощью функции DateTimeOffset.Now или DateTime.UtcNow

Если два выше, было бы рекомендовано запустить это на уровне презентации и передать его через службу на уровень домена или просто установить, когда он попадет в домен на задней стороне службы?

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

Боковое примечание: я также отслеживаю геопространственную информацию... но это не сложная система реального времени. Пользовательское время более чем достаточно.

UPDATE: я использую DateTimeOffset в приложении. Мое исследование привело меня к тому, что я обнаружил, что вы "можете надежно сравнить любые буксировки DateTimes, сначала называя ToUniversalTime на каждом из них. Эта стратегия терпит неудачу, если (и только если) точно один из них имеет DatTimeKind" Unspecified ". причина предпочтения DateTimeOffset" - С# 4.0 В двух словах, книги O'Riely.

Ответ 1

Я проголосую за настройку в процедуре (или по умолчанию для столбца, для вставок). Нет никаких оснований передавать всю эту информацию через все слои, если вам не нужна точность микросекунды для дифференциации, например. когда пользователь нажал кнопку против того, когда транзакция была зафиксирована в базе данных. Это особенно актуально, если у вас есть распределенное приложение - хотите ли вы полагаться на все веб-серверы/серверы приложений для синхронизации, не говоря уже о конечных рабочих станциях для клиентских/серверных приложений? У вас могут быть серверы в разных центрах обработки данных, все с разными часовыми поясами, некоторые наблюдающие DST, некоторые нет и т.д. DateTime.UtcNow должно уничтожить большинство этих различий, но я все равно вернусь к передаче всех этих данных без причины. База данных знает, что это за время; пусть он сохранит для вас значение и сохранит всю эту логику из приложения.

(Также, если вы сохраняете время UTC, вам действительно нужно DATETIMEOFFSET? Если это так, то вам все еще нужно каким-то образом определить порядок времени, в котором эта информация появилась. Если нет, то вам, вероятно, просто нужно используйте SMALLDATETIME/DATETIME/DATETIME2 в зависимости от требуемой точности.)