如何将DataSet.Fill与DateTime值默认为DateTimeKind.Utc?

时间:2009-11-10 23:40:18

标签: .net ado.net sqlclient

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

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

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

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

2 个答案:

答案 0 :(得分:16)

如果您使用的是SQL Server 2008,那么“正确”的解决方案是使用SQL datetimeoffset数据类型而不是SQL的日期时间。 datetimeoffset是SQL 2008新增的时区感知日期/时间类型,将在ADO.NET中转换为始终相对于UTC的CLR System.DateTimeOffset类型。这是一个blog post,详细介绍了这一点。 first few search results on MSDN for DateTimeOffset提供了其他背景信息。

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

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

如果您想要非常合适(或者如果上述方法不起作用),您可以提前创建DataTable并在DateTimeMode=DataSetDateTime.Utc之前设置该列的Fill - 用行。然后,您可以确保将日期作为UTC发送。

答案 1 :(得分:0)

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