我正在使用 OData 和 Web API 5.0,当我从 Queryable 序列化结果时,DateTime 字段总是缺少时区,显示如下:
StartTime: "2013-08-12T10:00:00"
我发现了一点微软 OData 实现,似乎 OData 使用自己的消息编写器进行序列化,所以我无法配置序列化程序以生成正确的带有时区的日期时间字符串。
有谁知道如何解决这个问题?
我正在使用 OData 和 Web API 5.0,当我从 Queryable 序列化结果时,DateTime 字段总是缺少时区,显示如下:
StartTime: "2013-08-12T10:00:00"
我发现了一点微软 OData 实现,似乎 OData 使用自己的消息编写器进行序列化,所以我无法配置序列化程序以生成正确的带有时区的日期时间字符串。
有谁知道如何解决这个问题?
如果你没有 sql 2008 或更高版本,你也可以将 nhibernate 中的数据类型设置为 utcdatetime。然后它只是假设日期时间是UTC,无论如何这是存储日期时间的唯一有效方式
如果您对 odata 接口中返回的确切数据类型有疑问,请检查 url 中的元数据:http: //odata.domain.org/.svc/$metadata。
您将看到类型 Edm.DateTime 用于本地时间字段和 Edm.DataTimeOffset 用于 UTC 字段。只有 UTC 会显示时区信息。
经过一番调查,我发现问题不是由 OData 引起的。
问题是由于 NHibernate 从 SQLSERVER 数据库读取的 DateTime 属性不包含 TimeZone 信息,因此如果没有此信息,OData 只能生成没有 TimeZone 的日期字符串。
请参考这个链接:它非常详细地解释了 NHibernate 日期时间问题
所以我对这个问题的解决方案是在 .NET 代码和 SQLSERVER 2008 中从 DateTime 切换到 DateTimeOffset 类型。然后在数据库中,DateTimeOffset 列保留 TimeZone 信息,当 NIBerate 读取时,它会将 TimeZone 信息传递给 .NET DateTimeOffset 属性。
从 SQLSERVER 2008 开始支持 DateTimeOffset。
“System.DateTime”类型不包含时区信息,要获取您需要使用“System.DateTimeOffset”的时区。
例如:
var dateTime = new DateTime(...);
var dtOffset = new DateTimeOffset(dateTime, new TimeSpan());
var dtOffset2 = new DateTimeOffset(dateTime, new TimeSpan(1,0,0));
//Assuming your pc is in the timezone GMT (+00:00)
// if you .ToString() each of the above you should get something like this ...
dateTime: "2013-08-12T10:00:00"
dtOffset: "2013-08-12T10:00:00+00:00"
dtOffset2: "2013-08-12T10:00:00+01:00"
如果您在 Windows 中更改 PC 的时区,则更改将应用于上面的“dateTime”变量,默认情况下,变量“dtOffset”将使用 Windows 指定的时区,但在“dtOffset2”变量中我指定了时区所以它总是固定为+01:00。
OASIS 已经从 OData 标准中删除了 DateTime,但我相信微软已经将它保留在他们的 OData 实现中,但是他们的实现假设 Offset 是机器偏移量。