Whenever I get a file from an HR department with a date in there, formatted like “21/12/2012” there could be problems…
When I receive this from HR, it’s in a file… it’s a string.
So when converting this to a datetime format, one could do the following:
1 |
[datetime]("21/12/2014") |
Well, this will give you an error, screaming that it’s an impossible date:
1 2 3 4 5 6 |
Cannot convert value "21/12/2014" to type "System.DateTime". Error: "String was not recognized as a valid DateTime." At line:1 char:1 + [datetime]("21/12/2014") + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [], RuntimeException + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider |
This is because of the standard in which dates are formatted. In case of my country, it’s: dd/mm/yyyy.
But in case of the USA, which for Windows systems is the standard, it’s: mm/dd/yyyy
So I’ve written a small function to convert this format to the format the datetime type accelerator accepts 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
function Convert-DateEuropeToUS { <# .SYNOPSIS Converts the date in a string from the European to the US format. .DESCRIPTION Converts the date in a string from the European, or Dutch specific (i don't know) to the US format. .PARAMETER Date Accepts a date in the dd-mm-yyyy or dd/mm/yyyy format. .Example JeffWouters.nl> "12/03/1985","03-12-1985" | Convert-DateEuropeToUS 3/12/1985 12/3/1985 .Example JeffWouters.nl> Convert-DateEuropeToUS "12/03/1985","03-12-1985" 3/12/1985 12/3/1985 #> [cmdletbinding()] param ( [parameter(mandatory=$true,position=0,valuefrompipeline=$true)][ValidatePattern("[0-9]{2}[/-]{1}[0-9]{2}[/-]{1}[0-9]{4}")]$Date ) begin { } process { foreach ($D in $Date) { $D = $D.replace('-','/') $a= [regex]::Replace($D,"(\w)(\w)(/)(\w)(\w)(/)(\w)(\w)(\w)(\w)",'$4$5/$1$2/$7$8$9$10') ([datetime]$a).ToShortDateString() } } end { } } |
That means you can use it like so:
1 |
[datetime](Convert-DateEuropeToUS "12/03/1985") |
Not sure i’m a fan of using regexps when there’s .NET methods to accomplish the task. I may of course have misunderstood and your intent is to showcase regexps in Powershell. Anyway, something like this should work fine
[System.DateTime]::Parse(’10/20/2014′,(New-Object system.globalization.cultureinfo ‘en-us’))
replace date-string and locale with proper values depending on the conversion. I leave it as an excersise to the reader to modify your function to take a date, source locale and output locale and convert to from any supported locales.
+1
[System.DateTime]::Parse(’10/11/2014′,(New-Object system.globalization.cultureinfo ‘fr-fr’))
#lundi 10 novembre 2014 00:00:00
[System.DateTime]::Parse(’10/11/2014′,(New-Object system.globalization.cultureinfo ‘en-us’))
#samedi 11 octobre 2014 00:00:00
(Convert-DateEuropeToUS ’10/11/2014′) -as [datetime]
#lundi 10 novembre 2014 00:00:00
#’10/11/2014′ -as [datetime]
#lundi 10 novembre 2014 00:00:00
Instead of manually creating a cultureinfo object why not just get the currently used culture and work with that? That way the command will work no matter what the underlying culture is:
[System.DateTime]::Parse(21/4/2016,([System.Globalization.CultureInfo]::CurrentCulture))
or:
[System.DateTime]::Parse(21/4/2016,(Get-Culture))
Sorry, I forgot the quotes around the dates:
[System.DateTime]::Parse(’21/4/2016′,([System.Globalization.CultureInfo]::CurrentCulture))
or:
[System.DateTime]::Parse(’21/4/2016′,(Get-Culture))