2015-05-04 12 views
12

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

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

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

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

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

+0

Ответ зависит от вашего двигателя базы данных, которые вы не указали. –

+0

@ DanBracuk Добавлена ​​подробная информация, спасибо. MSSQL2008 – Matthew

ответ

22

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

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

Вы сказали:

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

Я думаю, что, возможно, вы попали в формулировку в the user guide. Я вижу, как это может привести вас к этой линии мышления. Хотя верно, что логически 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)