Home > .NET, C# > DateOnly and TimeOnly support with System.Text.Json

DateOnly and TimeOnly support with System.Text.Json

22/11/2021

In .NET 6.0 we finally have DateOnly and TimeOnly, two long-awaited data types that allow to store, respectively, only a date (i.e., a birth date or an invoice date) or a time in day (for example, a recurring time for a meeting).

Unfortunately, System.Text.Json doesn’t provide built-in support for these new types. This means that, if we try to serialize a DateOnly or TimeOnly property, we got a NotSupportedException:

NotSupportedException when trying to serialize a DateOnly or TimeOnly property

NotSupportedException when trying to serialize a DateOnly or TimeOnly property

To overcome this issue, we need to create two ad-hoc Converters to handle these types, inherithing the JsonConverter class:

public class DateOnlyConverter : JsonConverter<DateOnly>
{
private readonly string serializationFormat;
public DateOnlyConverter() : this(null)
{
}
public DateOnlyConverter(string? serializationFormat)
{
this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
}
public override DateOnly Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
return DateOnly.Parse(value!);
}
public override void Write(Utf8JsonWriter writer, DateOnly value,
JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString(serializationFormat));
}

public class TimeOnlyConverter : JsonConverter<TimeOnly>
{
private readonly string serializationFormat;
public TimeOnlyConverter() : this(null)
{
}
public TimeOnlyConverter(string? serializationFormat)
{
this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
}
public override TimeOnly Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
return TimeOnly.Parse(value!);
}
public override void Write(Utf8JsonWriter writer, TimeOnly value,
JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString(serializationFormat));
}

In this way, we can make the serialization/deserialization work just adding the Converters to a JsonSerializerOptions instancee:


var date = DateOnly.FromDateTime(DateTime.Now);
var time = TimeOnly.FromDateTime(DateTime.Now);

var test = new DataTypeTest(date, time);

var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
options.Converters.Add(new DateOnlyConverter());
options.Converters.Add(new TimeOnlyConverter());

var json = System.Text.Json.JsonSerializer.Serialize(test, options);
var testBack =
    System.Text.Json.JsonSerializer.Deserialize<DataTypeTest>(json, options);

public record DataTypeTest(DateOnly Date, TimeOnly Time);

If you don’t want to add these Converters to all of your projects, you can use my small library, TinyHelpers, that is available on GitHub and NuGet and, among the other things, already provides them, as well as some other cool stuff 🙂

Advertisement
Categories: .NET, C# Tags: , ,
  1. totti240282
    22/11/2021 at 16:35

    Minerva the Best!

  2. elegs
    02/02/2022 at 19:00

    Superb. Thank you

  1. 23/11/2021 at 01:07
  2. 23/11/2021 at 13:46
  3. 23/11/2021 at 14:30
Comments are closed.
%d bloggers like this: