在 PowerShell 中,如何将使用逗号作为小数秒分隔符的 ISO 8601 时间戳转换为本机日期时间对象?

In PowerShell, how do I convert an ISO 8601 timestamp that uses a comma as the fractional second separator to a native datetime object?

如果我有一个符合 ISO 8601 标准且使用逗号作为小数秒分隔符的时间戳,例如:

$strTimestamp = '2021-08-31T23:12:11,5-05:00'

(即 2021-08-31 在 23:12:11 和 0.5 秒,UTC-5 偏移量)

如何将其转换为本机 PowerShell 日期时间?我试过:

Get-Date -Date $strTimestamp

但它抛出一个错误:

Get-Date: Cannot bind parameter 'Date'. Cannot convert value "2021-08-31T23:12:11,5-05:00" to type "System.DateTime". Error: "String '2021-08-31T23:12:11,5-05:00' was not recognized as a valid DateTime."

值得注意的是,使用句点而不是逗号的相同时间戳效果很好:

(Get-Date -Date '2021-08-31T23:12:11.5-05:00') | Format-List

Returns:

DisplayHint : DateTime
Date        : 8/31/2021 12:00:00 AM
Day         : 31
DayOfWeek   : Tuesday
DayOfYear   : 243
Hour        : 23
Kind        : Local
Millisecond : 500
Minute      : 12
Month       : 8
Second      : 11
Ticks       : 637660483315000000
TimeOfDay   : 23:12:11.5000000
Year        : 2021
DateTime    : Tuesday, August 31, 2021 11:12:11 PM

由于逗号分隔符符合标准,理想的答案是接受逗号、句号或根本不使用分隔符。

谢谢!

从实用的角度来说,将输入字符串中的 , 替换为 . 确实是最简单的解决方案:

'2021-08-31T23:12:11,5-05:00', # comma
'2021-08-31T23:12:11.4-05:00', # period
'2021-08-31T23:12:11-05:00' |  # no fractional part
  ForEach-Object {
    [datetime] ($_ -replace ',', '.')
  }

虽然 , 作为小数秒的小数点是 part of the ISO 8601 standard, as you state, the [datetime] (System.DateTime) type's Parse() method 不识别它(它只识别 .),不管有效的文化如何 - 至少作为.NET 5 / .NET 6 的预览版。

请注意 PowerShell 的 [datetime] '...' cast 相当于调用
[datetime]::Parse('...', [cultureinfo]::InvariantCulture),因为 PowerShell 默认应用 invariant 区域性(请参阅 了解 PowerShell 转换的一般概述)。

您可以使用 [datetime]::ParseExact 自定义格式

$strTimestamp = '2021-08-31T23:12:11,5-05:00'
[datetime]::ParseExact($strTimestamp, "yyyy-MM-ddTHH:mm:ss','fzzz", $null)
01 September 2021 05:12:11

请注意,这会根据时区进行调整。

如果您想忽略时区,请改用 [DateTimeOffset],其 DateTime 属性

$strTimestamp = '2021-08-31T23:12:11,5-05:00'
[DateTimeOffset]::ParseExact($strTimestamp, "yyyy-MM-ddTHH:mm:ss','fzzz", $null).DateTime
31 August 2021 23:12:11