1

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!

Frank Lesniak
  • 560
  • 1
  • 5
  • 18
  • 1
    It might be worth noting that I can do a string replacement of the comma with a period, and then the conversion works. Surely there's a better way? Example: Get-Date -Date (('2021-08-31T23:12:11,5-05:00').Replace(',', '.')) – Frank Lesniak Sep 01 '21 at 20:00
  • I would question whether or not the input conforms to ISO-8601. Does the standard permit a COMMA character before the fractional time element? Yes, it is what you must work with, but I am unsure that it could be said to be ISO-8601 format compliant. – lit Sep 01 '21 at 21:46
  • Yep - according to Wikipedia, the comma is preferred. See: https://en.wikipedia.org/wiki/ISO_8601#Times – Frank Lesniak Sep 01 '21 at 21:51
  • I would hope that PowerShell becomes more adept at handling ISO-8601 conformant data. – lit Sep 02 '21 at 01:44

2 Answers2

1

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).

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

You can use [datetime]::ParseExact with a custom format

$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

Note that this adjusts for the time zone.

If you want to ignore the time zone, use [DateTimeOffset] instead, with its DateTime property

$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
Charlieface
  • 52,284
  • 6
  • 19
  • 43