This is because
([datetime]"2022-02-15-1720").Kind
yields 'Local', while
([datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture)).Kind
returns 'Unspecified'
If you want the result to handle the string as being Local time and then the result should be in UTC, use:
([datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture, 'AssumeLocal')).ToUniversalTime()
or
$date = [datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture)
[datetime]::SpecifyKind($date, 'Local').ToUniversalTime()
Going the other way around, so if you regard the date in the string represents UTC (Universal Time), and you want the result to be in
Local time , you need to do this:
[datetime]::ParseExact("2022-04-29-185121", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture, 'AssumeUniversal')
Here, ParseExact()
treats the string as UTC and outputs a date converted to Local time
(.Kind
--> 'Local'), which is the exact same output as
[datetime]"2022-04-29-1851"
would give: also here, .Kind
--> 'Local'`
If then you want the resulting date to be in UTC, you need to convert it back again with .ToUniversalTime()
The tricky part is that using ParseExact()
without the third parameter ('AssumeLocal' or 'AssumeUniversal') when parsing a string that has no
indication of it being Local or UTC like the example strings here, is always returning a datetime object with its .Kind
property set to Unspecified.
Thanks to mklement0's comment,
in PowerShell (Core) 7+, strings like in the example are no longer recognized and should have a TimeZone indication like '2022-02-15 17:20Z'. ('Z' --> Zulu (UTC) Time)
If you do give it the third parameter, telling it what timezone it should use ('AssumeLocal' or 'AssumeUniversal'), the resulting datetime object will
always have its .Kind
property set to Local and the result will be converted to local time in case you have given AssumeUniversal
as parameter.