Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Text.Json: TimeSpan support #53908

Closed
wants to merge 2 commits into from

Conversation

CodeBlanch
Copy link
Contributor

Fixes #29932

Description

Adds TimeSpan support to System.Text.Json (Utf8JsonReader, Utf8JsonWriter, JsonElement, JsonSerializer, & JsonNode/JsonValue).

Uses Utf8Parser.TryParse & Utf8Formatter.TryFormat for the heavy lifting.

Public API Changes

    public readonly partial struct JsonElement
    {
       public System.TimeSpan GetTimeSpan() { throw null; }
       public bool TryGetTimeSpan(out System.TimeSpan value) { throw null; }
    }

    public ref partial struct Utf8JsonReader
    {
       public System.TimeSpan GetTimeSpan() { throw null; }
       public bool TryGetTimeSpan(out System.TimeSpan value) { throw null; }
    }

    public sealed partial class Utf8JsonWriter
    {
       public void WriteString(System.ReadOnlySpan<byte> utf8PropertyName, System.TimeSpan value) { }
       public void WriteString(System.ReadOnlySpan<char> propertyName, System.TimeSpan value) { }
       public void WriteString(string propertyName, System.TimeSpan value) { }
       public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.TimeSpan value) { }
       public void WriteStringValue(System.TimeSpan value) { }
    }

    public abstract partial class JsonNode
    {
       public static explicit operator System.TimeSpan (System.Text.Json.Nodes.JsonNode value) { throw null; }
       public static explicit operator System.TimeSpan? (System.Text.Json.Nodes.JsonNode? value) { throw null; }
       public static implicit operator System.Text.Json.Nodes.JsonNode (System.TimeSpan value) { throw null; }
       public static implicit operator System.Text.Json.Nodes.JsonNode? (System.TimeSpan? value) { throw null; }
    }

    public abstract partial class JsonValue
    {
       public static System.Text.Json.Nodes.JsonValue Create(System.TimeSpan value, System.Text.Json.Nodes.JsonNodeOptions? options = default(System.Text.Json.Nodes.JsonNodeOptions?)) { throw null; }
       public static System.Text.Json.Nodes.JsonValue? Create(System.TimeSpan? value, System.Text.Json.Nodes.JsonNodeOptions? options = default(System.Text.Json.Nodes.JsonNodeOptions?)) { throw null; }
    }

    public static partial class JsonMetadataServices
    {
       public static System.Text.Json.Serialization.JsonConverter<System.TimeSpan> TimeSpanConverter { get { throw null; } }
    }

Considerations

This is using the constant ("c") format. I think the general short format ("g") could compact things a bit, but not sure if that would round-trip with Newtonsoft and it is culture-sensitive.

/cc @layomia @eiriktsarpalis @JamesNK

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented Jun 9, 2021

Tagging subscribers to this area: @eiriktsarpalis, @layomia
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #29932

Description

Adds TimeSpan support to System.Text.Json (Utf8JsonReader, Utf8JsonWriter, JsonElement, JsonSerializer, & JsonNode/JsonValue).

Uses Utf8Parser.TryParse & Utf8Formatter.TryFormat for the heavy lifting.

Public API Changes

    public readonly partial struct JsonElement
    {
       public System.TimeSpan GetTimeSpan() { throw null; }
       public bool TryGetTimeSpan(out System.TimeSpan value) { throw null; }
    }

    public ref partial struct Utf8JsonReader
    {
       public System.TimeSpan GetTimeSpan() { throw null; }
       public bool TryGetTimeSpan(out System.TimeSpan value) { throw null; }
    }

    public sealed partial class Utf8JsonWriter
    {
       public void WriteString(System.ReadOnlySpan<byte> utf8PropertyName, System.TimeSpan value) { }
       public void WriteString(System.ReadOnlySpan<char> propertyName, System.TimeSpan value) { }
       public void WriteString(string propertyName, System.TimeSpan value) { }
       public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.TimeSpan value) { }
       public void WriteStringValue(System.TimeSpan value) { }
    }

    public abstract partial class JsonNode
    {
       public static explicit operator System.TimeSpan (System.Text.Json.Nodes.JsonNode value) { throw null; }
       public static explicit operator System.TimeSpan? (System.Text.Json.Nodes.JsonNode? value) { throw null; }
       public static implicit operator System.Text.Json.Nodes.JsonNode (System.TimeSpan value) { throw null; }
       public static implicit operator System.Text.Json.Nodes.JsonNode? (System.TimeSpan? value) { throw null; }
    }

    public abstract partial class JsonValue
    {
       public static System.Text.Json.Nodes.JsonValue Create(System.TimeSpan value, System.Text.Json.Nodes.JsonNodeOptions? options = default(System.Text.Json.Nodes.JsonNodeOptions?)) { throw null; }
       public static System.Text.Json.Nodes.JsonValue? Create(System.TimeSpan? value, System.Text.Json.Nodes.JsonNodeOptions? options = default(System.Text.Json.Nodes.JsonNodeOptions?)) { throw null; }
    }

    public static partial class JsonMetadataServices
    {
       public static System.Text.Json.Serialization.JsonConverter<System.TimeSpan> TimeSpanConverter { get { throw null; } }
    }

Considerations

This is using the constant ("c") format. I think the general short format ("g") could compact things a bit, but not sure if that would round-trip with Newtonsoft and it is culture-sensitive.

/cc @layomia @eiriktsarpalis @JamesNK

Author: CodeBlanch
Assignees: -
Labels:

area-System.Text.Json, new-api-needs-documentation

Milestone: -

@layomia layomia added this to the 6.0.0 milestone Jun 9, 2021
@layomia
Copy link
Contributor

layomia commented Jun 9, 2021

@CodeBlanch thanks for this contribution!

All the new API needs to go through API review before we can merge. Please feel free to add the proposed API to this issue #32965.

Most of the TimeSpan support requests I've seen are at the serializer level. I recommend splitting the PR into two separate PRs so that we can fast-track the support that most users are asking for.

  • Add TimeSpan support to JsonSerializer (minimal API additions; the JsonMetadataServices changes can remain in this PR)
  • Add TimeSpan support to the rest of System.Text.Json

@CodeBlanch
Copy link
Contributor Author

@layomia Added to the issue. I'll look for the review decision and go from there. I intended to just do a converter but then those were calling into Utf8JsonReader/Writer so I did those updates. That left it in a state where most things had TimeSpan support, but not all things. Felt wrong to leave it like that so I made it all consistent 🤷

@eiriktsarpalis
Copy link
Member

Echoing @layomia's comment I would recommend following the approach employed in #53539, and only put the JsonMetadataServices APIs for review. #32965 concerns adding TimeSpan support to Utf8JsonWriter/Utf8JsonReader and should be reviewed independently.

For now we really only need the following API:

public static partial class JsonMetadataServices
{
    public static System.Text.Json.Serialization.JsonConverter<System.TimeSpan> TimeSpanConverter { get; }
}

I'll add it to #29932 and mark it ready for review.

@stephentoub stephentoub added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Jun 9, 2021
@CodeBlanch
Copy link
Contributor Author

OK to wait and see what is approved and then go from there? It won't take long to spin up new PRs, just trying to minimize re-work.

@eiriktsarpalis
Copy link
Member

Yeah I think it would be a good idea to wait, just in case the API design gets revised.

@eiriktsarpalis
Copy link
Member

Hey @CodeBlanch, FYI the API has just been approved as proposed.

@CodeBlanch
Copy link
Contributor Author

Opened #54186

@CodeBlanch CodeBlanch closed this Jun 14, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jul 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json new-api-needs-documentation NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JsonSerializer support for TimeSpan in 3.0?
4 participants