Add a -DateKind parameter to ConvertFrom-Json to control how System.DateTime / System.DateTimeOffset values are constructed
See original GitHub issueFollow-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/Unspecifiedshould create[datetime]instances with the given.Kindvalue.- A timestamp without time-zone information (UTC offset or
Zsuffix) should be assumed to beLocal(a pitfall is that on calling.ToLocalTime()on something that was parsed asUnspecified, it is assumed to be a UTC value -[datetime]::new(<unspecified-datetime>.Ticks, 'Local')is the solution). - If
Unspecifiedis requested, any UTC offset /Zsuffix should be ignored.
- A timestamp without time-zone information (UTC offset or
-
Offsetshould 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
Zsuffix) should be assumed to be a caller-local timestamp.
- A timestamp without time-zone information (UTC offset or
-
Noneshould 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 trailingZLocal, 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
Utcinstance 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]::UtcNowand[datetime]::UtcNow.ToString()). -
Specific UTC offsets in the input are lost, because they are translated to a caller-local
Localinstance.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:11
- Comments:11 (7 by maintainers)

Top Related StackOverflow Question
The @PowerShell/wg-powershell-cmdlets discussed this and would accept adding a new parameter to allow user to opt-in.
Simple
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 Offsetyou should be able to get aDateTimeOffsetvalue 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 Noneas you would just get the raw string back.