我们正在C#4中开发一个使用SQL Server 2008 R2作为后端的应用程序。在极少数情况下,SQL Server Compact 4也用于断开连接的客户端。我们想知道将日期/时间数据存储到这些数据库中的最佳方式是什么,以便:
- 包含不同时间偏移(来自不同时区)的数据可以很好地共存。这意味着要进行排序和比较
- SQL Server 2008 R2和SQL Server Compact 4中的数据可以无缝地来回传输;这是一个次要要求,不应影响所选择的设计
我们主要关心的是为每个记录的事件保留本地时间,但又不失去比较和排序从不同时区生成的事件的能力,因此这些事件具有不同的时间偏移。
我们已经考虑了datetimeoffset
数据类型,因为它存储时间偏移,并且它很好地映射到.NET的DateTimeOffset
。但是,SQL Server Compact 4不支持它。另一种选择是从数据库中删除偏移信息,并使用简单的datetime
数据类型,这样数据库中的每一条数据都会被规范化,Compact的问题也会更少。然而,这引入了一个问题,即在用户看到数据之前,需要在检索时以某种方式重建偏移信息。
因此,我的问题是,考虑到我们需要处理不同的时区,并尽可能简化2008 R2和Compact 4之间的互操作性,是否有任何关于如何在SQL Server中存储日期/时间值的最佳实践或指导方针?
谢谢。
听起来相关的点是:
- 您的传入数据非常适合
DateTimeOffset
- 您只关心特定时间的偏移量,因此不需要真实时区。(偏移量不是时区。)
- 您确实关心原始偏移量-您不能将所有内容标准化为UTC并完全忽略偏移量
- 您想查询本地时间
听起来DateTimeOffset
基本上是这种情况下最合适的类型。不过,你应该确保团队中的每个人都清楚这意味着什么——偏移量是最初收到数据时的偏移量。如果您想在不同的时区中显示该时刻,您实际上需要回到UTC,并找出该显示时区中的偏移量。人们很容易对这类事情感到困惑:)
如果您需要在SqlServerCE中保持数据的完整性,您可能需要一个DateTime字段,然后为偏移量创建一个单独的字段(例如,以分钟为单位,或者如果SqlServerCE支持,则作为TimeSpan)。
在服务器上使用DateTimeOffset
可能是正确的。您可能还想阅读我关于DateTime与DateTimeOffset的回答。
在使用SQLCE的客户端上,存储一个具有UTC值的DateTime
。当您将数据发送到服务器时,您可以使用客户端的本地时区来确定UTC值对应的DateTimeOffset
。
如果用户可能正在更改时区,那么您可能还需要将时区的id存储在客户端数据库中。但你只需要在转换过程中使用它。没有必要将其发送到服务器,除非您可能正在服务器或其他客户端中编辑这些值。
不要尝试将客户端上的时间存储为客户端的本地时间。你会遇到歧义。例如,当夏令时向后滚动时,您不希望同一本地时间有两个不同的UTC时间。
为什么不使用日期时间并始终将值存储为UTC值,然后您可以根据需要将其格式化为最终用户(显示)时区。