Scarlet.System.Text.Json.DateTimeConverter 1.1.0

dotnet add package Scarlet.System.Text.Json.DateTimeConverter --version 1.1.0                
NuGet\Install-Package Scarlet.System.Text.Json.DateTimeConverter -Version 1.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Scarlet.System.Text.Json.DateTimeConverter" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Scarlet.System.Text.Json.DateTimeConverter --version 1.1.0                
#r "nuget: Scarlet.System.Text.Json.DateTimeConverter, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Scarlet.System.Text.Json.DateTimeConverter as a Cake Addin
#addin nuget:?package=Scarlet.System.Text.Json.DateTimeConverter&version=1.1.0

// Install Scarlet.System.Text.Json.DateTimeConverter as a Cake Tool
#tool nuget:?package=Scarlet.System.Text.Json.DateTimeConverter&version=1.1.0                

Overview

Nuget Nuget GitHub

This package allows you to specify a custom date format for DateTime, DateTimeOffset, and their nullable counterparts when serializing and deserializing JSON using System.Text.Json.

Installation

To install the Scarlet.System.Text.Json.DateTimeConverter package, run the following command in your terminal:

dotnet add package Scarlet.System.Text.Json.DateTimeConverter

Prerequisites

Make sure you have the appropriate .NET target framework installed. This package is compatible with the following versions:

  • .NET 6
  • .NET 7
  • .NET 8

Usage

Examples of how to serialize and deserialize models with custom date formats using JsonDateTimeConverter attribute and JsonDateTimeFormatConverter converter.

Note: The JsonDateTimeConverter attribute does not support System.Text.Json source generators. Using this attribute with JsonSerializerContext results in SYSLIB1223: "Attributes deriving from JsonConverterAttribute are not supported by the source generator."

In such cases, use the JsonDateTimeFormatConverter, which also works with reflection-based serialization and deserialization. The JsonDateTimeConverter attribute is simply less verbose and more readable than the JsonDateTimeFormatConverter.

Using reflection based only with JsonDateTimeConverter

This will work only with reflection-based serialization and deserialization.

public class MyModel
{
    [JsonDateTimeConverter("yyyy-MM-dd")]
    public DateTime Date { get; set; }

    [JsonDateTimeConverter("yyyy-MM-ddTHH:mm:ss.fffZ")]
    public DateTimeOffset DateTimeOffset { get; set; }
}

public class Program
{
    public static void Main()
    {
        var model = new MyModel
        {
            Date = DateTime.Now,
            DateTimeOffset = DateTimeOffset.Now
        };

        // Serialize
        string jsonString = JsonSerializer.Serialize(model);
        Console.WriteLine($"Serialized JSON: {jsonString}");

        // Deserialize
        var deserializedModel = JsonSerializer.Deserialize<MyModel>(jsonString);
        Console.WriteLine($"Deserialized Date: {deserializedModel.Date}");
        Console.WriteLine($"Deserialized DateTimeOffset: {deserializedModel.DateTimeOffset}");
    }
}

Using Source Generators with JsonDateTimeFormatConverter

To work with System.Text.Json source generators, use JsonDateTimeFormatConverter instead of JsonDateTimeConverterAttribute. This can also work with reflection-based serialization and deserialization.

public class MyModelSourceGenerator
{
    [JsonConverter(typeof(JsonDateTimeFormatConverter<JsonDateTimeFormat.DateTimeFormat>))]
    public DateTime Date { get; set; }

    [JsonConverter(typeof(JsonDateTimeFormatConverter<JsonDateTimeFormat.DateTimeOffsetFormat>))]
    public DateTimeOffset DateTimeOffset { get; set; }
}

internal class JsonDateTimeFormat
{
    internal class DateTimeOffsetFormat : IJsonDateTimeFormat
    {
        public static string Format => "yyyy-MM-ddTHH:mm:ss.fffZ";
    }
    
    internal class DateTimeFormat : IJsonDateTimeFormat
    {
        public static string Format => "yyyy-MM-ddTHH:mm:ss";
    }
}

[JsonSerializable(typeof(MyModelSourceGenerator))]
public sealed partial class MyModelSourceGeneratorJsonSerializerContext : JsonSerializerContext;

public class Program
{
    public static void Main()
    {
        var modelType = typeof(MyModelSourceGenerator);
        var model = new MyModelSourceGenerator
        {
            Date = DateTime.Now,
            DateTimeOffset = DateTimeOffset.Now
        };

        var context = MyModelSourceGeneratorJsonSerializerContext.Default;

        // Serialize
        string jsonString = JsonSerializer.Serialize(model, modelType, context);
        Console.WriteLine($"Serialized JSON: {jsonString}");

        // Deserialize
        var deserializedModel = (MyModelSourceGenerator?)JsonSerializer.Deserialize(jsonString, modelType, context);
        Console.WriteLine($"Deserialized Date: {deserializedModel.Date}");
        Console.WriteLine($"Deserialized DateTimeOffset: {deserializedModel.DateTimeOffset}");
    }
}

Unfortunately, there is no better way with the source generator than defining a class for each date-time format. This is because the JsonConverterAttribute is not supported by the source generator, and neither JsonConverterFactory nor JsonConverter allows passing the format string to the converter, as they lack constructors with parameters. The new contract customization does not provide attribute support for the source generator as well.

Notes

  • The JsonDateTimeConverterAttribute and JsonDateTimeFormatConverter can be applied to properties of type DateTime, DateTime?, DateTimeOffset, and DateTimeOffset?.
  • The format string provided to the attribute should follow the standard date and time format strings in .NET.
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 70 10/29/2024
1.0.0 62 10/28/2024