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

Почему Json.NET DeserializeObject изменяет часовой пояс на местное время?

Я использую json.net для десериализации DateTimeOffset, но он игнорирует указанный часовой пояс и преобразовывает datetime в локальное смещение. Например, данный

var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}";

При десериализации с использованием:

var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind };
var obj = JsonConvert.DeserializeObject(content, jsonSerializerSettings);

obj будет содержать свойство, содержащее DateTimeOffset, но значение будет 2012-07-19T15:30:00+10:30, то есть преобразуется в локальный часовой пояс вместо сохранения исходного часового пояса.

Есть ли способ получить значение, которое должно быть проанализировано так, как ожидалось, чтобы получившееся свойство DateTimeOffset соответствовало заданному значению?

4b9b3361

Ответ 1

Кажется, он игнорирует DateParseHandling.DateTimeOffset и использует DateParseHandling.DateTime. Я бы зарегистрировал проблему здесь: https://github.com/JamesNK/Newtonsoft.Json

Ответ 2

Если вы используете .NET WebApi, вы можете добавить следующее в файл WebApiConfig.cs для обработки этого в глобальном масштабе в своем приложении.

config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = 
    Newtonsoft.Json.DateTimeZoneHandling.Local;

Это будет специально указывать JsonFormatter, чтобы включать и понимать информацию о локальном часовом поясе при сериализации и десериализации даты.

Ответ 3

Попробуйте использовать это:

microsoftDateFormatSettings = new JsonSerializerSettings
{
    DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Local
};
var items = JsonConvert.DeserializeObject<List<lstObject>>(jsonString, microsoftDateFormatSettings);

Я не знаю, будет ли это работать во всех случаях, но для меня это было сделано. Вы можете попробовать другие значения для DateTimeZoneHandling или найти дополнительные параметры в Google.

Ответ 4

Я не уверен в том, какую версию вы использовали, потому что в какой-то момент времени у нас была та же проблема, а затем обновил ее...

Ваш код работает неправильно и для меня, но если я создаю класс вроде

public class A
{
    public DateTimeOffset startDateTime;
}

и вызовите

var obj = JsonConvert.DeserializeObject<A>(content, jsonSerializerSettings);

все работает так, как ожидалось. Да, это ошибка, да, я не знаю, как получить результат точно так, как вы хотите, но, вероятно, это поможет кому-то другому.

Ответ 5

Это работает для меня, сохраняется часовой пояс

var jss = new JsonSerializerSettings
    {
         DateFormatHandling = DateFormatHandling.IsoDateFormat,
         DateTimeZoneHandling = DateTimeZoneHandling.Local, 
         DateParseHandling = DateParseHandling.DateTimeOffset
    };
var responseObj = JsonConvert.DeserializeObject<dynamic>(body, jss);
return responseObj.Select(s => new {
                    id = s["id"].Value<int>(),
                    date = s["date"].Value<DateTimeOffset>().DateTime,
                });

Тело JSON похоже на это

[
    {
        "id": 211,
        "date": "2017-10-22T12:00:00+03:00",
        "status": 1
    },
    {
        "id": 212,
        "date": "2017-10-28T12:00:00+03:00",
        "status": 1
    }
]

Ответ 6

Чтобы использовать эти параметры в сериализаторе, введите:

var serializerSettings = new JsonSerializerSettings
            {
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                DateTimeZoneHandling = DateTimeZoneHandling.Local
            };
            var serializer = JsonSerializer.Create(serializerSettings);

Ответ 7

Проще говоря, вы можете преобразовать Date в Ticks для сериализации и преобразовать его из Ticks в Date для десериализации:

Сериализация:

DateTime date = new DateTime();
ticks = date.Ticks

десериализации "

Datetime = new Datetime(ticks);