I'm trying to use Json.NET to serialize some Noda Time values and having trouble. Serialization is simple enough:
LocalDateTime dt = ... // Assigned elsewhere
LocalDateTimePattern isoDateTimePattern = LocalDateTimePattern.GeneralIsoPattern;
JObject root = new JObject();
root.Add("time", isoDateTimePattern.Format(dt));
// Serialize other elements
using (var sw = new StreamWriter(stream)) {
serializer.Serialize(sw, root);
}
But deserialization is problematic. Json.NET seems to recognize the ISO-formatted date and time from above and automatically convert it into a DateTime object, which is not what I want.
using (var sr = new StreamReader(stream)) {
using (var jr = new JsonTextReader(sr)) {
var root = serializer.Deserialize<JObject>(jr);
// Deserialize other elements
var time = root.GetValue("time"); // time.Type is JTokenType.Date
string timeStr = time.Value<string>(); // Is "01/10/2014 10:37:32"
// Kaboom. String is not in the right format (see above comment)
var parsedTime = isoDateTimePattern.Parse(time.Value<string>());
}
}
From the fact that timeStr
comes out as a US-formatted date and time, I would guess that time.Value<string>()
just calls ToString
on some internal DateTime
object that Json.NET has already parsed.
I could do something like
var cdt = time.Value<DateTime>();
LocalDateTime ldt = new LocalDateTime(cdt.Year, cdt.Month, cdt.Day, cdt.Hour, cdt.Minute);
but that's convoluted and means Json.NET is performing unneeded conversions.
Is there any way to just get the raw string value of a JSON value?
There is a NodaTime.Serialization.JsonNet package available on NuGet that seems to be aimed exactly at this situation. Here is how to set it up:
After downloading and installing the package in your solution, add the following using
statement to your code:
using NodaTime.Serialization.JsonNet;
Set up your serializer like this:
JsonSerializer serializer = new JsonSerializer();
serializer.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
Then, when you deserialize, you can get a LocalDateTime
from the JObject
using ToObject<LocalDateTime>(serializer)
like this:
using (var sr = new StreamReader(stream))
{
using (var jr = new JsonTextReader(sr))
{
var root = serializer.Deserialize<JObject>(jr);
// Deserialize other elements
var time = root.GetValue("time");
var parsedTime = time.ToObject<LocalDateTime>(serializer);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With