7

我有一个应用程序,它可以从 SQL 读取数据并通过 WCF 将其发送到客户端应用程序,其方式类似于:

SqlDataAdapter da = new SqlDataAdapter( cmd )
DataSet ds = new DataSet();
da.Fill( ds );
return ds;

所有日期/时间都以 UTC 格式存储在数据库中。我注意到,如果运行应用程序的计算机上的时钟出现偏差,客户收到的日期/时间也会出现偏差。似乎如果 DateTime 类型是未指定的类型,WCF 将在内部将其表示为本地时间,并按原样发送,因此应用程序和客户端之间的任何时间差异都会导致日期/时间发生变化。

我当然可以在检索数据集并修复日期/时间字段时遍历它们,但是这里有人会想一些更好的方法来填充数据集,以便每个 DateTime 字段都会自动成为 da.Fill() 上的 DateTimeKind.Utc?

4

2 回答 2

18

如果您使用的是 SQL Server 2008,那么“正确”的解决方案是使用 SQLdatetimeoffset数据类型而不是 SQL 的日期时间。 datetimeoffset是 SQL 2008 新的时区感知日期/时间类型,将在 ADO.NET 中转换System.DateTimeOffset为始终相对于 UTC 的 CLR 类型。这是一篇博客文章,其中详细介绍了这一点。MSDN 上的前几个搜索结果DateTimeOffset提供了额外的背景信息。

如果您无法更改 SQL 架构,ADO.NET 有一个针对这种情况定制的属性:DataColumn.DateTimeMode,它控制在数据集序列化时是否添加本地时区(DateTimeMode=DataSetDateTime.UnspecifiedLocal默认为 ),或者是否不添加时区信息关于序列化 ( DateTimeMode=DataSetDateTime.Unspecified)。你想要后者。

如果我对 MSDN 文档的阅读是正确的,您应该能够在填充 DataSet 后DateTimeMode=DataSetDateTime.Unspecified为有问题的问题进行设置。DataColumn这应该序列化没有时区的列。

如果您想要真正正确(或者如果上述方法不起作用),您可以DataTable提前创建并设置该列的DateTimeMode=DataSetDateTime.Utcbefore Fill-ing 它与行。这样您就可以确保以 UTC 格式发送日期。

于 2009-11-11T06:11:06.383 回答
0

在我的例子中,将相关列的 DateTimeMode 属性值更改为“Unspecialed”,而不是 XSD 架构中的默认值“UnspecialedLocal”。

于 2019-02-22T01:19:51.293 回答