我有一个应用程序可以从SQL读取数据并通过WCF将其发送到客户端应用程序,方式与此类似:
SqlDataAdapter da = new SqlDataAdapter( cmd )
DataSet ds = new DataSet();
da.Fill( ds );
return ds;
所有日期/时间都以UTC格式存储在数据库中。我注意到,如果运行应用程序的计算机上的时钟偏差,客户端收到的日期/时间也会有所偏差。似乎在DateTime类型是未指定类型的情况下,WCF将在内部将其表示为本地时间,并且这样发送,因此应用程序和客户端之间的任何时间差异都将导致日期/时间转移。
我可以检索数据集并修复日期/时间字段,但是这里的任何人都会想到一些更好的方法来填充数据集,这样每个DateTime字段都会自动成为da.Fill上的DateTimeKind.Utc( )?
答案 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”。