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

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

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

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

Какой тип следует использовать для их сохранения?

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

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

4b9b3361

Ответ 1

A 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)