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

24

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

有时我将时间戳持久化到SQL Server 2008数据库中。我传统上在UTC中使用datetime2字段。这些时间戳将使用Noda创建。似乎将日期转换为Noda的Instant可能不太合适。

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

如果我在SQL中使用非整数,则可能会在我的应用程序层和数据访问层之间存在潜在的转换问题。然而,如果我持久化整数的Noda instant,则在同一层之间存在逻辑耦合......并且我将无法在SQL中执行简单的日期聚合,除非将其带入应用程序层或CLR中。

Noda指出,瞬时不能可靠地描述UTC,因为某些时间在UTC中从未发生过。

1个回答

44

datetime2是一种完全可以接受和正常的SQL类型,用于存储Instant。使用Instant.ToDateTimeUtc方法获取DateTime,然后像平常一样将其存储在SQL中。同样地,在从SQL检索值时,可以使用Instant.FromDateTimeUtc方法。

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

您说:

  

Noda认为瞬间无法可靠地描述为UTC,因为某些时间在UTC中从未发生过。

我认为您可能陷入了用户指南中的措辞中。我可以看到它如何引导您沿着那条思路进行。虽然逻辑上Instant不表示UTC,但它肯定可以可靠地用UTC来描述。只要这些术语是清晰明确的,它也可以用其他术语来描述。

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

不能这样说DateTime(除非它具有DateTimeKind.Utc),也不能这样说LocalDateTimeLocalDateLocalTime等。所有这些都不是一个瞬间的唯一明确表示。

至于其他映射:

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)

UDT = 用户定义类型 - Rolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接