Lord Jabol
Lord Jabol

Reputation: 37

Change date format in a filename

I would like to mass rename a bunch of documents that have a data at the end of a filename. Currently the format is DDMMYYYY and I would like to swap it to YYYYMMDD. Would there be an "easy" way of modifying that for files with various filenames? Each file name would always end in a date for the documents I want to modify. Example would be 123456-newfile-DDMMYYYY.docx

I have seen a few similar posts that dealt with dates but neither of them would work in my scenario. Any feedback would be most welcome!

Upvotes: 0

Views: 694

Answers (2)

JohnLBevan
JohnLBevan

Reputation: 24410

As a followup to your comment Cannot find an overload for "TryParseExact" and the argument count: "5". At line:9 char:4:

The issue is $datetime = $null.

Since the parameter expects a DateTime type, and DateTime is not nullable, the parameter can't be matched to a method signature.

Replace that with $datetime = [DateTime]::MinValue so you'll be using a valid DateTime value.

Similarly for the DateTimeStyles argument, use 'None' or [System.Globalization.DateTimeStyles]::None instead of $null.

Upvotes: 1

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174465

Let's start by solving the problem for a single file (see inline comments for explanation):

$file = Get-Item path\to\123456-newfile-17052022.docx

# start by splitting the file's basename (filename sans extension) 
# at the position immediately before the last 8 characters
$prefix, $datePart = $file.BaseName -split '(?=.{8}$)'

# test if the date-suffix is indeed a date in the expected format
$datetime = $null
if([datetime]::TryParseExact($datePart, 'ddMMyyyy', $null, $null, [ref]$datetime)){
    # we got a match, let's rename the file!
    $oldName = $file.Name
    $newName = '{0}{1:yyyyMMdd}{2}' -f $prefix,$datetime,$file.Extension
    $file |Rename-Item -NewName $newName
    Write-Host "Renamed file '${oldName}' to '${newName}'!"
}

Now that we have it solved for 1 file, solving it for multiple files can be achieved by simply wrapping the whole thing in a foreach loop:

foreach($file in Get-ChildItem path\to\files\*.docx -File){
    # start by splitting the file's basename (filename sans extension) 
    # at the position immediately before the last 8 characters
    $prefix, $datePart = $file.BaseName -split '(?=.{8}$)'
    
    # test if the date-suffix is indeed a date in the expected format
    $datetime = $null
    if([datetime]::TryParseExact($datePart, 'ddMMyyyy', $null, $null, [ref]$datetime)){
        # we got a match, let's rename the file!
        $oldName = $file.Name
        $newName = '{0}{1:yyyyMMdd}{2}' -f $prefix,$datetime,$file.Extension
        $file |Rename-Item -NewName $newName
        Write-Host "Renamed file '${oldName}' to '${newName}'!"
    }
}

Upvotes: 3

Related Questions