-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
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/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.