I feel silly that I cannot figure this one out on my own.
I have dates coming from the CarbonBlack API e.g. 2022-02-15-172040 which are in UTC
The [datetime]
type cast works fine if I remove the seconds portion of the string
PS M:\Scripts> [datetime]"2022-02-15-1720"
Tuesday, February 15, 2022 12:20:00 PM
I don't understand how it "knows" that is a UTC string. It is correct of course but I expected 5:20pm for the time portion. I wanted the seconds for the date so I went to parse exact as this doesn't match any format strings as far as I know
PS M:\Scripts> [datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss" ,[Globalization.CultureInfo]::CurrentUICulture)
Tuesday, February 15, 2022 5:20:40 PM
Which is the time I expected but the incorrect time.
Why is the [datetime]
working when I wouldn't expect it to and what do I need to do to the string or static method call for it to treat that as a UTC string with minimal manipulation?
This is because
yields 'Local', while
returns 'Unspecified'
If you want the result to handle the string as being Local time and then the result should be in UTC, use:
or
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:
Here,
ParseExact()
treats the string as UTC and outputs a date converted to Local time(
.Kind
--> 'Local'), which is the exact same output aswould 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 givenAssumeUniversal
as parameter.