jsonpowershelldatetimepowershell-7.2

Powershell 7.2: ConvertFrom-Json - Date Handling


With Powershell 7.2 there seems to be a change in how a JSON is deserialized into an object in terms of dates -> instead of string it is now datetime. But I want to have the "old" behavior, i.e. that it is handled as string and NOT datetime.

How can I achieve that when using ConvertFrom-Json in Powershell 7.2 all dates are deserialized as string and not datetime?

EDIT:

$val = '{ "date":"2022-09-30T07:04:23.571+00:00" }' | ConvertFrom-Json
$val.date.GetType().FullName

Solution

  • This is actually a known issue, see: #13598 Add a -DateKind parameter to ConvertFrom-Json to control how System.DateTime / System.DateTimeOffset values are constructed. Yet I think there is no easy solution for this. One thing you might do is just invoke (Windows) PowerShell. Which isn't currently straights forward as well therefore I have created a small wrapper to send and receive complex objects between PowerShell sessions (see also my #18460 Invoke-PowerShell purpose):

    function Invoke-PowerShell ($Command) {
        $SerializeOutput = @"
             `$Output = $Command
             [System.Management.Automation.PSSerializer]::Serialize(`$Output)
    "@
        $Bytes = [System.Text.Encoding]::Unicode.GetBytes($SerializeOutput)
        $EncodedCommand = [Convert]::ToBase64String($Bytes)
        $PSSerial = PowerShell -EncodedCommand $EncodedCommand
        [System.Management.Automation.PSSerializer]::Deserialize($PSSerial)
    }
    

    Usage:

    Invoke-PowerShell { '{ "date":"2022-09-30T07:04:23.571+00:00" }' | ConvertFrom-Json }
    
    date
    ----
    2022-09-30T07:04:23.571+00:00
    

    Update

    As commented by mklement0, I clearly complicated the answer.

    Calling via powershell.exe is a pragmatic workaround (albeit slow and Windows-only), but note that you don't need a helper function: if you pass a script block to powershell.exe (or pwsh.exe) from PowerShell, Based64 CLIXML-based serialization happens automatically behind the scenes: try powershell.exe -noprofile { $args | ConvertFrom-Json } -args '{ "date":"2022-09-30T07:04:23.571+00:00" }' For that reason, I don't think there's a need for an Invoke-PowerShell cmdlet.

    $Json = '{ "date":"2022-09-30T07:04:23.571+00:00" }'
    powershell.exe -noprofile { $args | ConvertFrom-Json } -args $Json
    
    date
    ----
    2022-09-30T07:04:23.571+00:00