Matthias Pospiech
Matthias Pospiech

Reputation: 3494

Convert date format from DD.MM.YYYY to YYYY-MM-DD

I have folders on the disk in the german format: "01.05.2019", which I want to convert into the english format: "2019-05-01".

I am using PowerShell. Is there a fancy function for doing this? Or should I get all substrings and reorder them?

Currently I only collect the strings:

$OrgDir = "P:\Fotos\Import"
$folders = Get-ChildItem $($OrgDir) -Directory 
foreach ($dir in $folders) {
    Write-Host "folder: " $dir
}

Upvotes: 3

Views: 4208

Answers (3)

Role
Role

Reputation: 1

Finally this did the trick for me:

PS> [datetime]::Parse('01.05.2019', [cultureinfo] 'de-DE').
      ToString('yyyy-MM-dd', [cultureinfo]::InvariantCulture)

All other solutions ended in:

Get-Date : Cannot bind parameter 'Date'. Cannot convert value "15.12.2019" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."

Thanks a lot mklement0.

Upvotes: 0

spicy.dll
spicy.dll

Reputation: 957

Use [DateTime]::ParseExact() to avoid the date parser mixing up the month and day:

$OrgDir = "P:\Fotos\Import"
$folders = Get-ChildItem $OrgDir -Directory
foreach ($dir in $folders) {
    Write-Host "folder: $([DateTime]::ParseExact($dir.Name, "dd.MM.yyyy", $null).ToString("yyyy-MM-dd"))"
}

The above prints out the converted names. To efficiently rename the files however, I recommend this:

Get-ChildItem $OrgDir -Directory | 
    ForEach-Object {
        $_ | Rename-Item -NewName (
            [DateTime]::ParseExact($_.Name, "dd.MM.yyyy", $null).ToString("yyyy-MM-dd")
        )
    }

This line of PowerShell renames all directories at $OrgDir to the new date format, given that all directories in the folder are named this way.

Reference


UPDATE:

As @Matt Johnson pointed out, $null uses your system default culture for ParseExact(string, format, culture) (as well as ToString(format, culture)). This may or may not cause problems based on what culture setting your system currently has.

To ensure these settings do not interfere with this function, use [System.Globalization.CultureInfo]::InvariantCulture for the culture parameters in both ParseExact() and ToString().

Upvotes: 4

mklement0
mklement0

Reputation: 437618

Matt Johnson provides important pointers in his comments:

To write robust code that works independently of what culture is in effect, specify the culture context explicitly, both when:

  • parsing strings as [datetime] instances

  • formatting [datetime] instances as strings

Therefore, use the following in your case:

PS> [datetime]::Parse('01.05.2019', [cultureinfo] 'de-DE').
      ToString('yyyy-MM-dd', [cultureinfo]::InvariantCulture)
2019-05-01
  • Since 01.05.2019 is a valid (day-first) short date in German, no custom parsing is needed, only de-DE (German / Germany) as the cultural context.

  • .ToString('yyyy-MM-dd', [cultureinfo]::InvariantCulture) specifies an explicit output-format string; [cultureinfo]::InvariantCulture - the invariant culture (based on US-English) - as the cultural context ensures that the date is interpreted based on the Gregorian calendar.

Note that in PowerShell casts (e.g., [datetime] '01.05.2019') and string interpolation (e.g., "$(get-date)") always use the invariant culture - whereas calling [datetime]::Parse() and .ToString() without an explicit culture (format-provider) argument uses the current culture.

Upvotes: 2

Related Questions