PowerShell [DateTime] throws the error "String was not recognized as a valid DateTime."
In some of my scripts, such as Get-AutoDiscoverRecords.ps1, I convert the string output of another command (such as an LDAP query) into a Date and Time variable by using the type cast [DateTime]. For example the following will turn the string "06/16/2016 3:14:03 PM" into a PowerShell DateTime object for June 16th 2016 at 3:14PM:
$DateTime = [DateTime]"06/16/2016 3:14:03 PM"
This works great in US based script executions because the DateTime type cast expects the format in the MM/dd/yyyy format, but other parts of the world use the dd/MM/yyyy format. For those other areas, the DateTime type cast with the locality modified string of "16/6/2016 3:14:03 PM" will throw the following error:
Cannot convert value "16/06/2016 15:14:03" to type "System.DateTime". Error: "String was not recognized as a valid DateTime.
Not only does this date and time format cause the DateTime type cast to fail on some month/day configurations, what's worse is that the string "02/06/2016 15:14:03" could be considered February 6th and not June 2nd. Beyond the flipping of the date and month, there are also cultural subtleties around the world (such as including AM/PM or not) that require special format handling to ensure a proper DateTime type case conversion.
To address those various issues so a PowerShell script can be run anywhere in the world, we can tell the DateTime type cast how to handle the string output by another command through parsing according to the local cultural settings with the following code:
# Extract the default Date/Time formatting from the local computer's "Culture" settings, and then create the format to use when parsing the date/time information pull from AD. $CultureDateTimeFormat = (Get-Culture).DateTimeFormat $DateFormat = $CultureDateTimeFormat.ShortDatePattern $TimeFormat = $CultureDateTimeFormat.LongTimePattern $DateTimeFormat = "$DateFormat $TimeFormat" $DateTime = [DateTime]::ParseExact("06/16/2016 3:14:03 PM",$DateTimeFormat,[System.Globalization.DateTimeFormatInfo]::InvariantInfo,[System.Globalization.DateTimeStyles]::None)
This code tells PowerShell to get the current Date/Time format according to the language/cultural settings chosen by the currently logged in user, extract the Date and Time formats separately, and then build the Date and Time format string to use for parsing input. The [DateTime] type cast line actually performs the parsing of the string "16/06/2016 3:14:03 PM" according to the cultural Date and Time formatting:
I have had colleagues in multiple countries test this code and it appears to force the DateTime type cast to interpret the date and time string correctly, and prevents the error above and also incorrectly interpreting the date and time. One colleague had to reboot their computer after changing their language settings to match the local language settings, because they had temporarily changed theirs to the US settings, but that was the only issue I have run into with this code.
So there you have it, if you ever need to convert a data and time string retrieved from another command via the DateTime type cast, you can use this code to ensure your script DateTime parsing is handled correctly no matter what the regional (cultural) standards for date and time formatting are.