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

Add (Try)GetDateTime(Offset) to Utf8JsonReader and JsonDocument #28459

Closed
ahsonkhan opened this issue Jan 19, 2019 · 8 comments
Closed

Add (Try)GetDateTime(Offset) to Utf8JsonReader and JsonDocument #28459

ahsonkhan opened this issue Jan 19, 2019 · 8 comments
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Text.Json
Milestone

Comments

@ahsonkhan
Copy link
Contributor

We should be consistent regarding what .NET types the Utf8JsonReader, Utf8JsonWriter, and JsonDocument support.

Since there is strong need for adding DateTime support (and the writer allows users to write one), we should add the following APIs to the reader and document.

Add:

public ref partial struct Utf8JsonReader
{
   // These throw InvalidOperationException if there is a token type mismatch (not a string)
   // Throws format exception if the string is not a DateTime (or DateTimeOffset)
   public DateTime GetDateTime();
   public DateTimeOffset GetDateTimeOffset();

   // These throw InvalidOperationException if there is a token type mismatch (not a string)
   public bool TryGetDateTime(out DateTime value);
   public bool TryGetDateTimeOffset(out DateTimeOffset value);
}
public readonly partial struct JsonElement
{
   public DateTime GetDateTime();
   public DateTimeOffset GetDateTimeOffset();

   public bool TryGetDateTime(out DateTime value);
   public bool TryGetDateTimeOffset(out DateTimeOffset value);
}

For consistency, we should remove Write(Guid) from the writer unless a customer requests it. If we want to keep Guid support, add it to the reader/document as well.

Remove:

public ref partial struct Utf8JsonWriter
{
        public void WriteString(System.ReadOnlySpan<byte> utf8PropertyName, System.Guid value, bool escape = true) { }
        public void WriteString(System.ReadOnlySpan<char> propertyName, System.Guid value, bool escape = true) { }
        public void WriteString(string propertyName, System.Guid value, bool escape = true) { }
        public void WriteStringValue(System.Guid value) { }
}

cc @bartonjs, @steveharter, @JamesNK

@ahsonkhan ahsonkhan changed the title Add (Try Add (Try)GetDateTime(Offset) to Utf8JsonReader and JsonDocument Jan 19, 2019
@JamesNK
Copy link
Member

JamesNK commented Jan 19, 2019

Things to think about:

  • Does it parse ISO8061 only or does it support all date formats, ala DateTime.Parse(s)
  • If it does support all date formats, what about culture?

@Tornhoof
Copy link
Contributor

we should remove Write(Guid) from the writer unless a customer requests it

Customer here, may I request it?
Examples: Keys in (no)sql databases, which sooner or later show up in storage payload and/or customer payload.

@Tornhoof
Copy link
Contributor

Does it parse ISO8061 only or does it support all date formats, ala DateTime.Parse(s)

Apparently long is still fairly popular, besides ISO8061.
Also make sure it supports parsing different millisecond precisions.

@JamesNK
Copy link
Member

JamesNK commented Jan 19, 2019

I don't think methods for Guid are that important. If Guid then why not TimeSpan, Uri, Version, etc. DateTime/DateTimeOffset are more common, and also I think it is worth offering an opinion about how they are written and read. Dates are a pain point in JSON and an obvious choice stops everyone going out and doing there own thing.

Apparently long is still fairly popular, besides ISO8061.

There is no way to know if an integer is ticks, or seconds since unix epoch.

@Tornhoof
Copy link
Contributor

Tornhoof commented Jan 19, 2019

If Guid then why not TimeSpan

Guid and Timespan are imho better choices, as we already have Utf8Parser/Formatter support. Neither Uri, nor Version have that afaik and need to go through string.

Timespan is as weird as datetime regarding formatting, even with ISO 8601 support, e.g. P1Y2M10DT2H30M (which I don't think many use).

I agree about long, but dto as long was one of the first custom format requests for spanjson, so I listed it here.

@terrajobst
Copy link
Contributor

terrajobst commented Feb 5, 2019

Video

Looks good.

We should consider applying the same principle from the writer to the reader: the writer differentiates between the underlying primitive and the convenience conversion (e.g. WriteString that takes a DateTime). For example, instead of GetDateTime() we'd have GetStringAsDateTime. That also makes it clear where we expect the value to come from, e.g. GetNumberAsInt32 makes it clear we won't parse the int from a string. And it makes the reader and the writer more consistent.

@layomia
Copy link
Contributor

layomia commented Feb 25, 2019

To start with, the (Try)GetDateTime(Offset) methods will by default parse input strings according to ISO 8061, but ignore CultureInfo and timezone conversion mechanisms. This means the output DateTime(Offset)’s timezone and kind will be the same as the input, if provided.

If the millisecond portion of the input string is provided, fraction digits will be truncated beyond 7 decimal places.

There is an internal DateTime UTF-8 parser that currently only supports a limited ISO 8601 format of "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK". A new parser will be added to support other valid, less restrictive ISO 8601 formats.

layomia referenced this issue in dotnet/corefx Mar 14, 2019
Add (Try)GetDateTime(Offset) to Utf8JsonReader

This change partially addresses https://github.com/dotnet/corefx/issues/34690.

These methods parse JSON strings to DateTime(Offset) objects according to format `YYYY-MM-DD[Thh:mm[:ss[.s]][TZD]]`
layomia referenced this issue in dotnet/corefx Mar 23, 2019
* Add (Try)GetGuid to Utf8JsonReader

This partially addresses https://github.com/dotnet/corefx/issues/34690.

* Address review feedback

* Address memory-related comments

* Address more review comments

* Re-add length check for span to be parsed

* Reduce code duplication
@layomia
Copy link
Contributor

layomia commented Apr 2, 2019

(Try)GetDateTime(Offset) and (Try)GetGuid methods have been added to Utf8JsonReader and JsonElement.

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Text.Json
Projects
None yet
Development

No branches or pull requests

6 participants