Skip to content

Add support for Date/TimeOnly to STJ #51302

@devsko

Description

@devsko

Background and Motivation

The recently added types DateOnly and TimeOnly should be fully supported by System.Text.Json. Even when it's possible to make them serializable via a built-in or custom converter, adding support to Utf8JsonReader/Writer brings them on par with other types like DateTimeOffset.

Proposed API

namespace System.Text.Json
{
    public ref partial struct Utf8JsonReader
    {
+        public DateOnly GetDateOnly();
+        public TimeOnly GetTimeOnly();
+        public bool TryGetDateOnly(out DateOnly value);
+        public bool TryGetTimeOnly(out TimeOnly value);
    }

    public sealed partial class Utf8JsonWriter
    {
+        public void WriteString(JsonEncodedText propertyName, DateOnly value);
+        public void WriteString(JsonEncodedText propertyName, TimeOnly value);
+        public void WriteString(string propertyName, DateOnly value);
+        public void WriteString(string propertyName, TimeOnly value);
+        public void WriteString(ReadOnlySpan<char> propertyName, DateOnly value);
+        public void WriteString(ReadOnlySpan<char> propertyName, TimeOnly value);
+        public void WriteString(ReadOnlySpan<byte> utf8PropertyName, DateOnly value);
+        public void WriteString(ReadOnlySpan<byte> utf8PropertyName, TimeOnly value);
+        public void WriteStringValue(DateOnly value);
+        public void WriteStringValue(TimeOnly value);
    }

    public readonly partial struct JsonElement
    {
+        public DateOnly GetDateOnly();
+        public TimeOnly GetTimeOnly();
+        public bool TryGetDateOnly(out DateOnly value)
+        public bool TryGetTimeOnly(out TimeOnly value)
    }
}

namespace System.Text.Json.Node
{
    public abstract partial class JsonNode
    {
+        public static explicit operator DateOnly(JsonNode value);
+        public static explicit operator TimeOnly(JsonNode value);
+        public static explicit operator DateOnly?(JsonNode? value);
+        public static explicit operator TimeOnly?(JsonNode? value);
+        public static implicit operator JsonNode(DateOnly value);
+        public static implicit operator JsonNode(TimeOnly value);
+        public static implicit operator JsonNode?(DateOnly? value);
+        public static implicit operator JsonNode?(TimeOnly? value);
    }
}

namespace System.Text.Json.Serialization.Metadata
{
    public static partial class JsonMetadataServices
    {
+        public static JsonConverter<DateOnly> DateOnlyConverter { get; }
+        public static JsonConverter<TimeOnly> TimeOnlyConverter { get; }
    }
}

namespace System.Buffers.Text
{
    public static partial class Utf8Formatter
    {
+        public static bool TryFormat(DateOnly value, Span<byte> destination, out int bytesWritten, StandardFormat format = default);
+        public static bool TryFormat(TimeOnly value, Span<byte> destination, out int bytesWritten, StandardFormat format = default);
    }
    public static partial class Utf8Parser
    {
+        public static bool TryParse(ReadOnlySpan<byte> source, out DateOnly value, out int bytesConsumed, char standardFormat = default);
+        public static bool TryParse(ReadOnlySpan<byte> source, out TimeOnly value, out int bytesConsumed, char standardFormat = default);
    }
}

Usage Examples

    var value = reader.GetDateOnly();
    writer.WriteStringValue(value);

Alternative Designs

As mentioned it would be possible to just add serialization converters for these types without supporting the Utf8Reader/Writer scenarios.

Risks

Obviously this API cannot be added to platforms prior .NET 6. Thus it would be necessary to only include it in the .NET 6 version of STJ.

Updates

  • Added Utf8Formatter.TryFormat and Utf8Parser.TryParse overloads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions