【问题标题】:Azure time zone and javascriptserializer objectAzure 时区和 javascriptserializer 对象
【发布时间】:2011-06-24 08:48:50
【问题描述】:

我有一个基于预测的应用程序,它在 Windows Azure (http://ipredikt.com) 上运行。据我所知,Azure 的时钟与 GMT 时区同步。这是我遇到的一个问题:

假设我有一个类型为 DateTime 的名为 CreateDate 的数据库字段,我将其值设置为 2011 年 6 月 10 日凌晨 12:30。创建新预测时。如果我在 db 表内窥视,则日期设置正确。我不会以任何方式触摸或更改此值。但是,当我使用我们的 API 读取该值,将其序列化并将其发送给客户端时,我会得到一个值为 2011 年 6 月 9 日下午 5:30 的日期。 (API dll 也存在于云端,可能与 DB 并置。)

我的客户端浏览器在 PST(太平洋时区)运行,似乎 7 小时的差异是由于 PST 和 GMT 之间的差异。用于序列化值的 API 代码类似这样:

System.Web.Script.Serialization.JavaScriptSerializer 序列化器 = new JavaScriptSerializer();

return serializer.Serialize(dataObject);

这是 JavaScriptSerializer 对象中的错误还是有修复此增量的技巧?基本上,我不希望 .NET 框架以任何方式干扰这个值,我只希望 DB 字段按原样返回。

【问题讨论】:

    标签: azure timezone javascriptserializer


    【解决方案1】:

    当您将 DateTime 对象传递给 Azure 时,它​​的 Kind 等于 Local。
    (2011 年 6 月 10 日 12:30am-7)

    但是,当您将其保存到数据库时,区域信息会丢失。随后,当从数据库中读取此字段时,它会使用 Utc 区域创建 DateTime (2011 年 6 月 10 日凌晨 12:30 0)

    最终,您的客户端会错误地读取日期时间。

    有几个选项可以解决这个问题。

    1) 在方法参数和数据库中将 DateTime 转换为 DateTimeOffset。这将保证您的本地区域(即 PST)将保存在 db 中

    2) 使用 DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified) - 这样 DateTime 的类型是未指定的,随后按原样保存在数据库中。

    var timeNow = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
    serviceClient.SaveTime(timeNow);
    var dateTime = serviceClient.GetTime();
    

    【讨论】:

    • 这一切都说得通,我觉得这正是正在发生的事情。但是,我尝试了您建议的解决方案 2,但没有运气。在保存和从数据库读取时,我已经尝试了 DateTimeKind 的所有组合,但我仍然在客户端上获得了增量。事实上,我不确定为什么在将日期时间值保存到数据库时需要指定任何内容。当我查看表格时,该值为 2011-06-10 00:00:00.000(我在上面的示例中仅使用 12:30 以避免混淆,但我确实将时间设置为 00:00 am)。因此,在阅读它时,我尝试了 Local、Utc 和 Unspecified,但我仍然得到 -7 的增量。
    • 在以下示例中,我使用的是 wcf,并且在 sql azure 端有实体框架。 var timeNow = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified); serviceClient.SaveTime(timeNow); var dateTime = serviceClient.GetTime();结果 dateTime 的 Kind 等于 Unspecified。它可以“在我的机器上”运行
    • 我考虑了你所说的关于 Azure 日期的内容,并通过这样做解决了 javascript 本身的问题: var dd = new Date($idDueDate.val()); oPrediction.DueDate = new Date(dd.toUTCString());在实际保存到数据库之前。 Azure 完全按照您上面的描述更改了日期。谢谢大家。
    【解决方案2】:

    序列化的 Json 响应中可能出现的日期是“自纪元以来的毫秒数”格式的日期,并且还应该包括时区信息,然后浏览器在显示相对于本地时区的日期时会考虑这些信息。

    所有这些都是正确的行为,所以没有错误。在您的情况下,您似乎不希望这种行为。

    .NET 日期具有“种类”属性。如果未指定,则假定为 UTC。序列化程序在序列化时应考虑“种类”属性。尝试在序列化之前检查对象上的此属性,并将其更改为 DateTimeKind.Local。

    http://msdn.microsoft.com/en-us/library/system.datetime.kind.aspx

    或者,您可以查看浏览器端的自定义反序列化,在反序列化之前将时区部分从序列化日期中剥离出来。

    【讨论】:

    • 相当多,但如果我没记错的话,您需要将其设置为 DateTimeKind.Unspecified 以便在跨时区边界进行序列化/反序列化时不会更改时间。
    • 当我在序列化之前检查对象的“Kind”属性时,它被设置为未指定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多