如果应用程序使用 NodaTime,我应该如何在 SQL 数据库中保留时间戳?

How should I persist timestamps in SQL DB if app uses NodaTime?

我想开始在我的应用程序中使用 NodaTime 来管理时间、瞬间和一般时间本地化。

有时我将时间戳保存到 SQL Server 2008 数据库中。我传统上使用 UTC 中的 datetime2 字段。这些时间戳将使用 Noda 创建。似乎这个日期转换为 Noda 的 Instant 可能是不可取的。

我应该使用什么类型来持久化它们?

如果我在 SQL 中使用非整数,那么我的 App 层和 DAL 之间可能存在转换问题。但是,如果我坚持使用整数 Noda 即时,我将在相同层之间建立逻辑耦合......并且我将无法在 SQL 中执行简单的日期聚合而不将其带入应用程序层或 CLR。​​

Noda 指出无法用 UTC 可靠地描述瞬间,因为某些时间从未在 UTC 中出现。

datetime2 是一种完全可以接受的正常 SQL 类型来存储 Instant。使用 Instant.ToDateTimeUtc 方法获取 DateTime,然后照常将其存储在 SQL 中。同样,您可以在从 SQL.

中检索值时使用 Instant.FromDateTimeUtc 方法

或者,如果您想明确表示值是基于 UTC 的(偏移量始终为零),则可以使用 SQL datetimeoffset 类型。在 Instant 上有 ToDateTimeOffsetFromDateTimeOffset 方法你可以使用。

你说:

Noda makes the case that instants can't reliably be described in UTC, since certain times never occurred in UTC.

我想您可能对 the user guide 中的措辞感到困惑。我可以看到它如何引导你沿着这条思路走下去。虽然逻辑上 Instant 确实不代表 UTC,但就 UTC 而言,它肯定可以可靠地 描述 。它也可以用其他一些术语来描述,只要这些术语是明确的。

用户指南的要点是,UTC 中 不是 的其他值仍然可以转换为 Instant。例如,我可能有一个 OffsetDateTimeDateTimeOffset,其偏移量 与零不同 ,并且它仍然可以调整回零以形成Instant。同样,我可能有一个分配给 UTC 时区或其他时区的 ZonedDateTime,我仍然可以返回到单个通用 Instant 而不会丢失保真度。

相同的 不能 DateTime(除非它有 DateTimeKind.Utc),或 LocalDateTimeLocalDate , LocalTime, 等 None 无疑是一个瞬间。

就其他映射而言:

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)