If I have an ISO 8601-compliant timestamp that uses a comma as the fractional second seperator, e.g.:
$strTimestamp = '2021-08-31T23:12:11,5-05:00'
(i.e., 2021-08-31 at 23:12:11 and 0.5 seconds, UTC-5 offset)
How do I convert this to native PowerShell datetime? I've tried:
Get-Date -Date $strTimestamp
but it throws an error:
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."
It's worth noting that the same timestamp with a period instead of a comma works just fine:
(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
Since the comma separator is compliant with the standard, an ideal answer would accept a comma, a period, or no separator at all.
Thanks!
Pragmatically speaking, replacing ,
with .
in your input strings is indeed the simplest solution your case:
'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 ',', '.')
}
While ,
as the decimal mark for fractional seconds is part of the ISO 8601 standard, as you state, the [datetime]
(System.DateTime
) type's Parse()
method doesn't recognize it (it only recognizes .
), irrespective of the culture in effect - at least as of .NET 5 / the preview versions of .NET 6.
Note that PowerShell's [datetime] '...'
cast is the equivalent of calling
[datetime]::Parse('...', [cultureinfo]::InvariantCulture)
, because PowerShell applies the invariant culture by default (see this answer for an overview of PowerShell's casts in general).