Как сохранить временные метки в базе данных SQL, если приложение использует NodaTime?

Я хочу начать использовать NodaTime в своем приложении для управления временем, моментами и общей локализацией времени.

Иногда я сохраняю метки времени в базе данных SQL Server 2008. Я традиционно использовал поля datetime2 в UTC. Эти временные метки будут созданы с использованием Noda. Кажется, что это преобразование даты в Нода Instant может быть нежелательным.

Какой тип я должен использовать, чтобы сохранить их?

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

Нода утверждает, что моменты не могут быть надежно описаны в UTC, поскольку в UTC никогда не происходило определенное время.

1 ответ

Решение

datetime2 является вполне приемлемым и нормальным типом SQL для хранения Instant, Использовать Instant.ToDateTimeUtc способ получить DateTime, затем сохраните это в SQL как обычно. Кроме того, вы можете использовать Instant.FromDateTimeUtc метод при получении значения из SQL.

В качестве альтернативы вы можете использовать SQL datetimeoffset введите, если вы хотите явно указать, что значения основаны на UTC (смещение всегда будет равно нулю). Есть ToDateTimeOffset а также FromDateTimeOffset методы на Instant ты можешь использовать.

Вы сказали:

Нода утверждает, что моменты не могут быть надежно описаны в UTC, поскольку в UTC никогда не происходило определенное время.

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

Суть в том, что руководство пользователя делает то, что другие значения, которые не в UTC, все еще могут быть преобразованы в Instant, Например, я мог бы иметь OffsetDateTimeили DateTimeOffset который имеет смещение, отличное от нуля, и он все еще может быть скорректирован до нуля, чтобы сформировать Instant, Точно так же я мог бы иметь ZonedDateTime который назначен часовому поясу UTC или некоторому другому часовому поясу, я все еще могу вернуться к одному универсальному Instant без потери верности.

То же самое нельзя сказать о DateTime (если это не имеет DateTimeKind.Utc) или LocalDateTime, LocalDate, LocalTimeи т. д. Ни одно из них не является однозначным моментом времени.

Что касается других отображений:

Noda Time      | .NET BCL                   | SQL Server
---------------|----------------------------|------------------------------------------
Instant        | DateTime or DateTimeOffset | datetime2 or datetimeoffset
OffsetDateTime | DateTimeOffset             | datetimeoffset
LocalDateTime  | DateTime                   | datetime2
LocalDate      | DateTime                   | date
LocalTime      | TimeSpan                   | time
Duration       | TimeSpan                   | int or bigint (Ticks, TotalSeconds, etc.)
Period         | String                     | varchar
ZonedDateTime  | DateTimeOffset + String    | datetimeoffset + varchar (or a UDT)
Другие вопросы по тегам