Как сохранить временные метки в базе данных 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)