question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add a -DateKind parameter to ConvertFrom-Json to control how System.DateTime / System.DateTimeOffset values are constructed

See original GitHub issue

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.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:11
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
SteveL-MSFTcommented, Dec 7, 2022

The @PowerShell/wg-powershell-cmdlets discussed this and would accept adding a new parameter to allow user to opt-in.

2reactions
jborean93commented, Nov 2, 2022

Simple

ConvertFrom-Json -InputObject '{"Date": "2022-11-02T12:01:44.5801388-04:00"}' | ConvertTo-Json

When you use ConvertFrom-Json on this field it gives you a Local Kind DateTime object which has a correct value but you no longer know the original value is -04:00. It would only work if your local time zone was also -04:00.

If you were able to do -DateKind Offset you should be able to get a DateTimeOffset value back where the time zone offset is preserved allowing you to round trip the data back but also be able to know what the input value’s time zone was. Same with -DateKind None as you would just get the raw string back.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Powershell 7.2: ConvertFrom-Json - Date Handling
This is actually a known issue, see: #13598 Add a -DateKind parameter to ConvertFrom-Json to control how System.DateTime / System.
Read more >
DateTime and DateTimeOffset support in System.Text.Json
The System.Text.Json library parses and writes DateTime and DateTimeOffset values according to the ISO 8601-1:2019 extended profile.
Read more >
Disable conversion to UTC timezone after deserialization of a ...
Kind value depends on the specifics of the string value: ... #13598 proposes adding a -DateTimeKind parameter to ConvertFrom-Json , so as to ......
Read more >
Specifying the Kind on DateTime
In your setter, you should only use SpecifyKind if the value.DateTimeKind is Unspecified. · It's only ever set by the constructor or the...
Read more >
[Mono-patches] [mono/monkeywrench] [3 commits] e2b9b294
Json/Converters/DateTimeConverterBase.cs A Newtonsoft. ... Threading; +using System. ... Value); + return parent; + } + + public static void ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found