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