How to deserialize an `Instant` without the final Z with NodaTime and `System.Text.Json`?

51 Views Asked by At

I need to deserialize a JSON string with .NET's System.Text.Json containing a date time in UTC, but I'm unable to use the NodaTime converter for Instant since the string is missing the final Z (even though it's UTC).

I'm using the following code:

public record Item(Instant date);
var options = new JsonSerializerOptions()
    .ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

var item = JsonSerializer.Deserialize<Item>(options);

And I'm getting the following error:

 ---> System.Text.Json.JsonException: Cannot convert value to NodaTime.Instant
 ---> NodaTime.Text.UnparsableValueException: The value string does not match a quoted string in the pattern. Value being parsed: '2023-10-20T10:10:22^'. (^ indicates error position.)
1

There are 1 best solutions below

0
mcont On

The solution is to build a converter for the expected format manually:

var options = new JsonSerializerOptions
{
    Converters =
    {
        new NodaPatternConverter<Instant>(InstantPattern.CreateWithInvariantCulture("uuuu-MM-ddTHH:mm:ss"))
    }
};

Similar thing if you wanted to do that with another type, for example with LocalDateTime and a format that is unsupported by the default converters:

var options = new JsonSerializerOptions
{
    Converters =
    {
        new NodaPatternConverter<LocalDateTime>(LocalDateTimePattern.CreateWithInvariantCulture("uuuu-MM-dd HH:mm:ss"))
    }
};