Подтвердить что ты не робот

JavaScriptSerializer вычитает один день с даты

Я использую 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, но я получаю на один день меньше первоначальной даты.

4b9b3361

Ответ 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!

Ответ 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();

он решил проблему.

Ответ 3

У меня была та же проблема и она была решена с помощью

Newtonsoft.Json.JsonConvert.SerializeObject()

вместо

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

Последний вызов хранит вашу DateTime, преобразованную в некоторый случайный часовой пояс (GMT + 0, похоже, жестко запрограммирован).