web-dev-qa-db-ja.com

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プロパティが提供された値と一致するように、期待どおりに値を解析する方法はありますか?

32
Dave Capper

DateParseHandling.DateTimeOffsetを無視しているようで、DateParseHandling.DateTimeを使用しています。ここに問題を記録します: https://github.com/JamesNK/Newtonsoft.Json

15
Peter Ritchie

.NET WebApiを使用している場合は、WebApiConfig.csファイルをアプリケーションでグローバルに処理します。

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

これは、日付をシリアライズおよびデシリアライズするときに、ローカルタイムゾーン情報を含めて理解するようにJsonFormatterに具体的に指示します。

12
txavier

これを使ってみてください:

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

それがすべての場合に機能するかどうかはわかりませんが、私にとってはうまくいきました。 DateTimeZoneHandlingに他の値を試すか、Googleでその他のオプションを検索できます。

9
Grey Wolf

ある時点で同じ問題が発生したため、どのバージョンを使用したかはわかりませんが、更新して修正しました...

あなたのコードは私にとっても間違って機能しますが、次のようなクラスを作成すると

public class A
{
    public DateTimeOffset startDateTime;
}

そして電話する

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

すべてが期待どおりに機能します。はい、それは確かにバグです、はい、私はあなたが望むとおりに結果を得る方法を知りませんが、おそらく、それは他の誰かのために役立つでしょう。

8
chopikadze

これは私にとってはうまくいきます、タイムゾーンは保持されます

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
    }
]
3

シリアライザーでこれらの設定を使用するには、次を入力します。

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