web-dev-qa-db-fra.com

Pourquoi Json.NET DeserializeObject change le fuseau horaire en heure locale?

J'utilise json.net pour désérialiser une DateTimeOffset, mais il ignore le fuseau horaire spécifié et convertit la date/heure en décalage local. Par exemple, étant donné

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

Lors de la désérialisation en utilisant:

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

L'obj contiendra une propriété contenant un DateTimeOffset mais la valeur sera 2012-07-19T15:30:00+10:30 c'est-à-dire convertie dans le fuseau horaire local au lieu de conserver le fuseau horaire d'origine.

Existe-t-il un moyen d'obtenir que la valeur soit analysée comme prévu afin que la propriété DateTimeOffset résultante corresponde à la valeur fournie?

29
Dave Capper

Il semble ignorer DateParseHandling.DateTimeOffset et utilise DateParseHandling.DateTime. Je voudrais enregistrer un problème ici: https://github.com/JamesNK/Newtonsoft.Json

15
Peter Ritchie

Si vous utilisez .NET WebApi, vous pouvez ajouter ce qui suit dans le fichier WebApiConfig.cs pour gérer cela globalement dans votre application.

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

Ceci indiquera spécifiquement à la JsonFormatter d'inclure et de comprendre les informations de fuseau horaire local lors de la sérialisation et de la désérialisation d'une date.

10
txavier

Essayez d'utiliser ceci:

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

Je ne sais pas si cela fonctionnera dans tous les cas, mais pour moi, cela a fonctionné. Vous pouvez essayer d'autres valeurs pour DateTimeZoneHandling ou rechercher d'autres options sur Google.

8
Grey Wolf

Je ne suis pas sûr de savoir quelle version avez-vous utilisée, car à un moment donné, nous avions le même problème, puis la mise à jour l'a corrigé ...

Votre code fonctionne mal pour moi aussi, mais si je crée une classe comme

public class A
{
    public DateTimeOffset startDateTime;
}

et appeler

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

tout fonctionne comme prévu. Oui, c'est un bogue, oui, je ne sais pas comment obtenir le résultat exactement comme VOUS le souhaitez, mais cela aidera probablement quelqu'un d'autre.

7
chopikadze

Cela fonctionne pour moi, un fuseau horaire est préservé

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,
                });

Un corps JSON est quelque chose comme ça

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

Pour utiliser ces paramètres dans le sérialiseur, tapez:

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