首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Powershell 7.2:转换-Json-日期处理

Powershell 7.2:转换-Json-日期处理
EN

Stack Overflow用户
提问于 2022-11-04 09:09:14
回答 3查看 113关注 0票数 3

使用Powershell 7.2,在日期、->而不是字符串方面,JSON反序列化为对象的方式似乎发生了变化,现在是日期时间。但我希望有“旧”行为,即它是作为字符串处理的,而不是日期时间。

在Powershell 7.2中使用ConvertFrom时,如何实现所有日期都反序列化为字符串而不是日期时间?

编辑:

代码语言:javascript
运行
复制
$val = '{ "date":"2022-09-30T07:04:23.571+00:00" }' | ConvertFrom-Json
$val.date.GetType().FullName
EN

回答 3

Stack Overflow用户

发布于 2022-11-04 15:14:27

  • 铁的有用答案通过 PowerShell CLI、 提供了一种实用的解决方案,该解决方案依赖于ConvertFrom-Json不会自动将ISO 8601类时间戳字符串转换为[datetime]实例这一事实。
代码语言:javascript
运行
复制
- Hopefully, the proposal in the GitHub issue he links to, [#13598](https://github.com/PowerShell/PowerShell/issues/13598), will be implemented in the future, which would then simplify the solution to:

尚未实现,截至PowerShell 7.2.x '{“日期”:“2022-09-30T07:04:23.571+00:00”}‘PowerShell从-Json -DateTimeKind无转换

  • 但是,powershell.exe解决方案有两个缺点:(a)速度慢(必须启动子进程中的单独PowerShell实例),(b)它仅限于Windows。下面的解决方案是您自己的方法的概括,以避免这些问题。

这里是generalization of 你自己的过程中的方法

  • 它在与时间戳模式匹配的每个字符串的开头注入一个NUL字符("`0") --假设输入本身从未包含这样的字符,这是合理的假设。
  • 与您的方法一样,这会阻止ConvertFrom-Json识别时间戳字符串,并且保持不变。
  • 然后必须对[pscustomobject]输出的ConvertFrom-Json图进行后处理,以便再次删除注入的NUL字符。
代码语言:javascript
运行
复制
- This is achieved with a [`ForEach-Object`](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/foreach-object) call that contains a helper script block that _recursively_ walks the object graph, which has the advantage that it  **works with JSON input whose timestamp strings may be** _**at any level of the hierarchy**_ (i.e. they may also be in properties of _nested_ objects).
代码语言:javascript
运行
复制
- **Note**: The assumption is that the timestamp strings are only ever contained as _property values_ in the input; more work would be needed if you wanted to handle input JSON such as `'[ "2022-09-30T07:04:23.571+00:00" ]'` too, where the strings are input objects themselves.
代码语言:javascript
运行
复制
# Sample JSON.
$val = '{ "date":"2022-09-30T07:04:23.571+00:00" }'

$val -replace '"(?=\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{2}:\d{2}")', "`"`0" |          #"
  ConvertFrom-Json |
  ForEach-Object {
    # Helper script block that walks the object graph
    $sb = {
      foreach ($o in $args[0]) { 
        if ($o -is [Array]) { # nested array -> recurse
          foreach ($el in $o) { & $sb $el } # recurse
        }
        elseif ($o -is [System.Management.Automation.PSCustomObject]) {
          foreach ($prop in $o.psobject.Properties) { 
            if ($prop.Value -is [Array]) {
              foreach ($o in $prop.Value) { & $sb $o } # nested array -> recurse
            }
            elseif ($prop.Value -is [System.Management.Automation.PSCustomObject]) { 
              & $sb $prop.Value # nested custom object -> recurse
            }
            elseif ($prop.Value -is [string] -and $prop.Value -match '^\0') { 
              $prop.Value = $prop.Value.Substring(1) # Remove the NUL again.
            }
          } 
        }
      }
    }
    # Call the helper script block with the input object.
    & $sb $_
    # Output the modified object.
    if ($_ -is [array]) {
      # Input object was array as a whole (implies use of -NoEnumerate), output as such.
      , $_ 
    } else {
      $_
    }
  } 
票数 2
EN

Stack Overflow用户

发布于 2022-11-04 14:31:56

基于@zett42 42的输入,我的解决方案如下:

假设我们知道JSON中使用的日期的regex模式,我将JSON作为字符串,添加一个前缀,这样ConvertFrom-Json就不会将日期转换为datetime,而是将它保持为string,用ConvertFrom-Json将它转换为PSCustomObject,对对象做我需要做的任何事情,用ConvertTo-Json将它序列化回JSON字符串,然后再次删除前缀。

代码语言:javascript
运行
复制
[string]$json = '{ "date":"2022-09-30T07:04:23.571+00:00", "key1": "value1" }'

[string]$jsonWithDatePrefix = $json -replace '"(\d+-\d+.\d+T\d+:\d+:\d+\.\d+\+\d+:\d+)"', '"#$1"'

[pscustomobject]$jsonWithDatePrefixAsObject = $jsonWithDatePrefix | ConvertFrom-Json

$jsonWithDatePrefixAsObject.key1 = "value2"

[string]$updatedJsonString = $jsonWithDatePrefixAsObject | ConvertTo-Json

[string]$updatedJsonStringWithoutPrefix = $updatedJsonString -replace '"(#)(\d+-\d+.\d+T\d+:\d+:\d+\.\d+\+\d+:\d+)"', '"$2"'

Write-Host $updatedJsonStringWithoutPrefix
票数 0
EN

Stack Overflow用户

发布于 2022-11-07 20:38:04

另外两种更改日期格式的方法:

Get-Node

使用这个类似于Get-Node递归函数的mklement0

代码语言:javascript
运行
复制
$Data = ConvertFrom-Json $Json
$Data |Get-Node -Where { $_.Value -is [DateTime] } | ForEach-Object {
    $_.Value  = GetDate($_.Value) -Format 'yyyy-MM-ddTHH\:mm\:ss.fffzzz' -AsUTC
}
$Data

DIY

或者自己动手构建自己的Json反序列化器:

代码语言:javascript
运行
复制
function ConvertFrom-Json {
    [CmdletBinding()][OutputType([Object[]])] param(
        [Parameter(ValueFromPipeLine = $True, Mandatory = $True)][String]$InputObject,
        [String]$DateFormat = 'yyyy-MM-ddTHH\:mm\:ss.fffffffzzz', # Default: ISO 8601, https://www.newtonsoft.com/json/help/html/datesinjson.htm
        [Switch]$AsLocalTime,
        [Switch]$AsOrdered
    )
    function GetObject($JObject) {
        switch ($JObject.GetType().Name) {
            'JValue' {
                switch ($JObject.Type) {
                    'Boolean'  { $JObject.Value }
                    'Integer'  { 0 + $JObject.Value }                                                 # https://github.com/PowerShell/PowerShell/issues/14264
                    'Date'     { Get-Date $JObject.Value -Format $DateFormat -AsUTC:(!$AsLocalTime) } # https://github.com/PowerShell/PowerShell/issues/13598
                    Default    { "$($JObject.Value)" }
                }
            }
            'JArray' {
                ,@( $JObject.ForEach{ GetObject $_ } )
            }
            'JObject' {
                $Properties = [Ordered]@{}
                $JObject.ForEach{ $Properties[$_.Name] = GetObject $_.Value }
                if ($AsOrdered) { $Properties } else { [PSCustomObject]$Properties }                  # https://github.com/PowerShell/PowerShell/pull/17405
            }
        }
    }
    GetObject ([Newtonsoft.Json.Linq.JObject]::Parse($InputObject))
}

使用:

代码语言:javascript
运行
复制
ConvertFrom-Json $Json -DateFormat 'yyyy-MM-ddTHH\:mm\:ss.fffzzz' |ConvertTo-Json -Depth 9
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74314557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档