JavaScriptSerializer 正在从日期中减去一天
Posted
技术标签:
【中文标题】JavaScriptSerializer 正在从日期中减去一天【英文标题】:JavaScriptSerializer is subtracting one day from date 【发布时间】:2013-02-06 20:10:16 【问题描述】:我正在使用 javascriptSerializer
序列化 DateTime,但是当我反序列化它时,它显示的日期比序列化日期少了一天:
这里是测试:
DateTime startDate=new DateTime(2012,1,20);//set the 20th of January
JavaScriptSerializer serializer=new JavaScriptSerializer();
string serializeDate= serializer.Serialize(startDate);
DateTime afterDeserialize= serializer.Deserialize<DateTime>(serializeDate);//I get 19th of Jan
Assert.Equals(startDate, afterDeserialize);
首先我认为它是因为 javascript datetime 格式,但我知道 javascript Month 是零索引 0=January
,但我比原始日期少了一天。
【问题讨论】:
解决方案 1:搞砸时区等。解决方案 2:只需将年、月和日存储为单独的值,然后在反序列化后重新组合。 【参考方案1】:它不会任意浪费一天,它会转换为 UTC 日期(或者我应该说使用 UTC 日期格式的日期),所以当它被反序列化时,你不再在你的个人时区内。它基本上在执行:
DateTime whateverDate = /* incoming date */;
long ticks = whateverDate.ToUniversalTime() // make UTC
.Subtract(new DateTime(1970, 1, 1)) // subtract UNIX Epoch
.TotalMilliseconds(); // get milliseconds since then
// push in to the "\/Date(ticks)\/" format
String value = String.Format(@"\/Date(0)\/", ticks);
但是,请尝试以下操作:
// or you rely on it serializing, then bring it back to your own local time
// (apply the time zone).
afterDeserialize = afterDeserialize.ToLocalTime();
您现在将 UTC 时间恢复为您的本地时间(应用时区)。
通过测试:
DateTime startDate = new DateTime(2012,1,20);
JavaScriptSerializer serializer = new JavaScriptSerializer();
String serializeDate = serializer.Serialize(startDate);
DateTime afterDeserialize = serializer.Deserialize<DateTime>(serializeDate)
.ToLocalTime(); // Note: this is added
Assert.Equals(startDate, afterDeserialize); // pass!
【讨论】:
这是documented behavior,虽然很不清楚。 DateTime startDate = new DateTime(2012, 1, 20).ToUniversalTime();它将 startDate 设置为 1 月 19 日?并在反序列化时得到相同的结果......为什么会这样? blog.devarchive.net/2008/02/… 这是一篇非常详细地解释问题的博客 @ZaheerAhmed - 它正在改变时区。您的日期附加了一个隐含的午夜,因此您可能会在时区转换中损失几个小时,从而导致日期发生变化。 我的时区是PST,如何在同一个时区输入和输出。【参考方案2】:我遇到了同样的问题并通过使用解决了它
Newtonsoft.Json.JsonConvert.SerializeObject()
而不是
new System.Web.Script.Serialization.JavaScriptSerializer().Serialize().
后一个调用将您的 DateTime 转换为某个随机时区(GMT+0 似乎是硬编码的)。
【讨论】:
【参考方案3】:在反序列化 JavaScriptSerializer
时给我在 UTC (Universal Time)
中的输出,由于时间的变化会改变日期。正如Brad Christie
建议将DateTime 更改为UTC 可以解决问题。
但其实没必要改:
DateTime startDate = new DateTime(2012, 1, 20).ToUniversalTime();
因为它已经将其作为世界时间。所以我只是将反序列化的输出转换为LocalTime
:
DateTime afterDeserialize= serializer.Deserialize<DateTime>(serializeDate);
afterDeserialize.ToLocalTime();
它解决了这个问题。
【讨论】:
有趣的是,刚刚在我的答案更新中输入了该内容。 ;-) :),将您的答案标记为正确,并将其放在这里,以便对其他人有所帮助以上是关于JavaScriptSerializer 正在从日期中减去一天的主要内容,如果未能解决你的问题,请参考以下文章
泛型/JSON JavaScriptSerializer C#
JavaScriptSerializer 可以排除具有空值/默认值的属性吗?
带有 Razor 和 ASPX 引擎的 JavaScriptSerializer