JSON.NET で ISO8601 規格の日付時刻文字列を JObject に DateTimeOffset として読み込む
◆ はじめに
今さら JSON.NET かよって感じですが、仕事中にはまったのでメモ。
やりたいことは、JSON 内の ISO8601規格の日付時刻文字列を一旦 JObject に変換して、
変換した JObject から DatetimeOffset の値を取得したい。
◆ 何も考えずにやるとこうなる
素直に実装してみる。
Program.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
namespace DateTimeOffsetParseSample
{
class Program
{
static void Main(string[] args)
{
using (var stream = new StreamReader(@"Json\sample_data.json"))
{
var json = stream.ReadToEnd();
// json -> JObject
var data = JsonConvert.DeserializeObject<JObject>(json);
// JObject から DateTimeOffset 取得
var createdAtUtc = data.Value<DateTimeOffset>("created_at_utc");
var createdAtJst = data.Value<DateTimeOffset>("created_at_jst");
Console.WriteLine(createdAtUtc);
Console.WriteLine(createdAtJst);
}
Console.ReadLine();
}
}
}
Json\sample_data.json
{
"created_at_utc": "2019-02-11T04:50:40Z",
"created_at_jst": "2019-02-11T13:50:40+09:00"
}
実行してみるとわかるが、var createdAtUtc = data.Value<DateTimeOffset>("created_at_utc");
の部分で例外が発生する。
System.InvalidCastException
HResult=0x80004002
Message='System.DateTime' から 'System.DateTimeOffset' への無効なキャストです。
Source=mscorlib
なんでや。Value<DateTimeOffset>
してるのに。
◆ 解決方法
結論 DeserializeObject の引数で、日付変換設定を渡してあげれば良い。
Program.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
namespace DateTimeOffsetParseSample
{
class Program
{
static void Main(string[] args)
{
using (var stream = new StreamReader(@"Json\sample_data.json"))
{
var json = stream.ReadToEnd();
// json -> JObject
var settings = new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.DateTimeOffset,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
};
var data = JsonConvert.DeserializeObject<JObject>(json, settings);
// JObject から DateTimeOffset 取得
var createdAtUtc = data.Value<DateTimeOffset>("created_at_utc");
var createdAtJst = data.Value<DateTimeOffset>("created_at_jst");
Console.WriteLine(createdAtUtc);
Console.WriteLine(createdAtJst);
}
Console.ReadLine();
}
}
}
結果
2019/02/11 4:50:40 +00:00
2019/02/11 13:50:40 +09:00
めでたし、めでたし。
◆ まとめ
こんなことやりたい人がどれだけいるのかはわからないけど、知ってればなんてことない話。
ちなみに、JObject 経由しない場合だと、何も考えずに変換できる。なんでや。
あと、JSON.NET のキャラクターはなんかむかつく。以上。