20

我正在使用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,但我比原始日期少一天。

4

3 回答 3

20

它不会任意浪费一天,它正在转换为 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!
于 2013-02-21T13:30:45.147 回答
4

我有同样的问题并通过使用解决了它

Newtonsoft.Json.JsonConvert.SerializeObject()

代替

new System.Web.Script.Serialization.JavaScriptSerializer().Serialize().

后一个调用将您的 DateTime 转换为某个随机时区(GMT+0 似乎是硬编码的)。

于 2016-01-07T11:56:07.463 回答
2

在反序列化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();

它解决了这个问题。

于 2013-02-21T13:48:54.927 回答