从 ISO 8601 持续时间获取 DateTime 对象

Get a DateTime object from an ISO 8601 duration

在 PowerShell 中,有什么方法可以将 duration as specified by ISO 8601 转换为 DateTime 对象吗?例如,PT30M 是 30 分钟前,所以如果现在时间是 2019-07-31 17:00:00 我想要一个时间戳 2019-07-31 16:30:00.

我已经尝试了显而易见的 -

"PT30M" | Get-Date

但是那(不出所料地失败了)

Get-Date : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

我的下一个想法是编写一个函数来提取天、小时和分钟(例如,最多只有 30 天)。为此,下面的函数起作用并根据传入的 $Duration 创建 $startTime

不过,感觉有点不对。首先,正则表达式只非常具体地检查天数、分钟数和小时数,而 $Duration 的其余部分可能完全是垃圾。其次,要考虑到秒、周、月之类的东西,就很麻烦了。

是否有内置的方法来执行此操作,或者是否坚持使用低于最佳选项的功能?

function Get-TimespanFromDuration
{
    param(
        [Parameter(Mandatory)]
        [string]$Duration
    )

    $now = (Get-Date).ToUniversalTime()
    $dataTimeAgo = @{ "Days" = 0; "Hours" = 0; "Minutes" = 0 }

    ### Work out how may days ago.
    $daysAgo = $Duration -match "\D([1-9]|[1-2][0-9]|30)D"
    if ($daysAgo)
    {
        [int]$dataTimeAgo["Days"] = $matches[0] -replace "\D+"
    }

    ### Work out how may hours ago.
    $hoursAgo = $Duration -match "\D([1-9]|1[0-9]|2[0-4])H"
    if ($daysAgo)
    {
        [int]$dataTimeAgo["Hours"] = $matches[0] -replace "\D+"
    }

    ### Work out how many minutes ago.
    $minutesAgo = $Duration -match "\D([1-9]|[1-5][0-9]|60)M"
    if ($minutesAgo)
    {
        [int]$dataTimeAgo["minutes"] = $dataTimeAgo["minutes"] + ($matches[0] -replace "\D+")
    }

    $startTime = $now.AddDays(-($dataTimeAgo["Days"])).AddHours(-($dataTimeAgo["hours"])).AddMinutes(-($dataTimeAgo["minutes"])).ToString("yyyy-MM-ddTHH:mm:ss.0Z")
    $endTime = $now.ToString("yyyy-MM-ddTHH:mm:ss.0Z")

    return ("{0}/{1}" -f $startTime, $endTime)
}

有一个 .NET class 您可以在 PowerShell 中使用:[System.Xml.XmlConvert]::ToTimeSpan("PT30M")

不幸的是,这不适用于一周的持续时间。例如将“P20W”持续时间转换为时间跨度失败: [system.Xml.XmlConvert]::ToTimeSpan("P20W") MethodInvocationException:使用“1”个参数调用“ToTimeSpan”的异常:“字符串 'P20W' 不是有效的 TimeSpan 值。”

按照ISO_8601定义标准,为有效期,见: https://en.wikipedia.org/wiki/ISO_8601