JavaScriptSerializer UTC DateTime проблемы

Наш клиент хотел отображать значения даты и времени в браузере точно так же, как они есть в базе данных, и мы храним их как UTC в базе данных.

Сначала у нас были некоторые проблемы с сериализацией и Javascript. Значения DateTime были сдвинуты дважды - сначала, чтобы соответствовать местному часовому поясу машины, а затем, чтобы соответствовать часовому поясу в браузере. Мы исправили это, добавив пользовательский конвертер в JavaScriptSerializer. Мы пометили DateTime как DateTimeKind.Utc в переопределении Serialize. Было немного сложно вернуть данные из Serialize, но мы нашли некоторый хак Uri, который помог вернуть значения DateTime в том же формате JavaScriptSerializer / Date (286769410010) /, но без перехода на местное время. Со стороны Javascript мы исправили библиотеку JS KendoUI, чтобы сместить построенные объекты Date (), чтобы они выглядели так, как если бы они были UTC.

Затем мы начали работать на другой стороне, десериализации. Опять же, нам пришлось настроить наш код для использования пользовательской stringify вместо JSON.stringify, которая снова смещает данные при преобразовании из местного времени в UTC. Пока все было хорошо.

Но посмотрите на этот тест:

    public void DeserialiseDatesTest()
    {
        var dateExpected = new DateTime(1979, 2, 2,
            2, 10, 10, 10, DateTimeKind.Utc);

        // this how the Dates look like after serializing
        // anothe issue, unrelated to the core problem, is that the "\" might get stripped out when dates come back from the browser
        // so I have to add missing "\" or else Deserialize will break
        string s = "\"\\/Date(286769410010)\\/\"";

        // this get deserialized to UTC date by default
        JavaScriptSerializer js = new JavaScriptSerializer();

        var dateActual = js.Deserialize<DateTime>(s);
        Assert.AreEqual(dateExpected, dateActual);
        Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind);

        // but some Javascript components (like KendoUI) sometimes use JSON.stringify 
        // for Javascript Date() object, thus producing the following:
        s = "\"1979-02-02T02:10:10Z\"";

        dateActual = js.Deserialize<DateTime>(s);
        // If your local computer time is not UTC, this will FAIL!
        Assert.AreEqual(dateExpected, dateActual);

        // and the following fails always
        Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind); 
    }

Почему JavaScriptSerializer десериализуется\/Date(286769410010)\/ строки по времени UTC, но1979-02-02T02:10:10Zпо местному времени?

Мы попытались добавить метод десериализации к нашемуJavascriptConverter но проблема в том, что десериализация никогда не вызывается, если наш JavascriptConverter имеет следующие типы:

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new List<Type>() { typeof(DateTime), typeof(DateTime?) }; }
    }

Я думаю, десериализация будет вызвана только еслиSupportedTypes содержит типы некоторых сложных объектов, которые имеют поля DateTime.

Так,JavaScriptSerializer а такжеJavascriptConverter есть две несоответствия:

Serialize учитывает простые типы в SupportedTypes для каждого элемента данных, но Deserialize игнорирует его для простых типов.Десериализация десериализует некоторые даты как UTC, а некоторые - как местное время.

Есть ли простой способ исправить эти проблемы? Мы немного боимся заменитьJavaScriptSerializer с другим сериализатором, потому что, возможно, некоторые из сторонних библиотек, которые мы используем, полагаются на некоторые "особенности / ошибки"JavaScriptSerializer.

Ответы на вопрос(1)

Ваш ответ на вопрос