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 a -DateKind parameter to ConvertFrom-Json to control how System.DateTime / System.DateTimeOffset values are constructed #13598

Open
mklement0 opened this issue Sep 8, 2020 · 0 comments

Comments

@mklement0
Copy link
Contributor

@mklement0 mklement0 commented Sep 8, 2020

Follow-up from #13592:

Summary of the new feature/enhancement

Introduce a new -DateKind parameter as an enumeration value as follows:

ConvertFrom-Json -DateKind { Local | Utc | Unspecified | Offset | None }

The goal is to parse timestamps in the input JSON as [datetime] / [datetimeoffset] instances of the given kind - irrespective of the specific formatting of those timestamps.

  • Local / Utc / Unspecified should create [datetime] instances with the given .Kind value.

    • A timestamp without time-zone information (UTC offset or Z suffix) should be assumed to be Local (a pitfall is that on calling .ToLocalTime() on something that was parsed as Unspecified, it is assumed to be a UTC value - [datetime]::new(<unspecified-datetime>.Ticks, 'Local') is the solution).
    • If Unspecified is requested, any UTC offset / Z suffix should be ignored.
  • Offset should create a [datetimeoffset] instance instead, which preserves the exact UTC offset as specified or implied in the input.

    • A timestamp without time-zone information (UTC offset or Z suffix) should be assumed to be a caller-local timestamp.
  • None should not create a date a [datetime] / [datetimeoffset] at all and instead pass the original string values through.

Note that on serializing, with ConvertTo-Json, both Utc and Local [datetime] instances serialize with the appropriate UTC offset (e.g., "2020-09-08T16:24:21.577822-04:00"), whereas Unspecified serializes without an offset (e.g., "2020-09-08T16:24:21.577822").

Motivation:

Since v6, the Json.NET-based ConvertTo-Json automatically deserializes strings that contain an "o"-formatted (roundtrip format) date/time string (e.g., "2020-09-07T09:44:13.769Z") or a prefix of it that at least includes everything up to the seconds part (e.g., "2020-09-07T09:44:13:) as [datetime] instances.

However, the resulting [datetime] instances' .Kind property (Local, Utc, or Unspecified) is determined by the specifics of the string value as follows:

  • Unspecified, if there is no time-zone information in the input string.
  • Utc, if the time-zone information is a trailing Z
  • Local, if the time-zone information is given as a trailing UTC offset (e.g., +02:00), in which case the offset is properly converted to the caller-local equivalent.

Note that the new System.Text.Json API that is being considered as the future underpinning of the *-Json cmdlets - see #11198 - exhibits the same behavior.

There are two problems with this behavior:

  • A Utc instance gives no indication that it is a UTC timestamp in its default output formatting (applies both to PowerShell's formatting and .ToString() - verify with [datetime]::UtcNow and [datetime]::UtcNow.ToString()).

  • Specific UTC offsets in the input are lost, because they are translated to a caller-local Local instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.