PlTaylor
PlTaylor

Reputation: 7525

Trouble with [datetime]::parseexact

I know I must be missing something simple, but I've stared at it for a while and can't seem to see it.

I have the following powershell code

.".\Get-FileMetaDataReturnObject.ps1"

$BaseDirectory = "C:\Users\me\Desktop\Photo Test"

$Folders = get-childitem -path $BaseDirectory -Directory
foreach ($folder in $folders)
{
    Write-Host "Folder name:$($folder.Name)"
    $picture = Get-ChildItem -Path "$BaseDirectory\$($folder.Name)\"
    $picMetaData = Get-FileMetaData  -folder "$BaseDirectory\$($folder.Name)\"
    $picDate = $picMetaData | Select 'Date Taken'
    $picDateTaken = $picDate[0].'Date taken'
    Write-Host $picDateTaken
    $dateTime = [datetime]::parseexact($picDateTaken, "M/d/yyyy h:mm tt", [System.Globalization.CultureInfo]::InvariantCulture)
    $dateStr = $dateTime.ToString('yyyy-MM-dd')
    Write-Host $dateStr

}

When I run it I get the following error

Folder name:Deruta - Umbria, September 4, 2012
‎9/‎4/‎2012 ‏‎4:12 PM
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At C:\Users\me\Desktop\Picture Folder Rename\PhotoFolderRename.ps1:18 char:5
+    $dateTime = [datetime]::parseexact($picDateTaken, "M/d/yyyy h:mm  ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException

The meta data script is found here

I'm really not sure what I've screwed up with the date time parsing, so any help would be appreciated.

Upvotes: 0

Views: 188

Answers (1)

Jeroen Mostert
Jeroen Mostert

Reputation: 28779

Comparing "9/‎4/‎2012 ‏‎4:12 PM".Length (20) with "9/4/2012 4:12 PM".Length (16) shows us something fishy is going on, and indeed this string is not what it appears to be; there are U+200E LEFT-TO-RIGHT MARK and U+200F RIGHT-TO-LEFT MARK control characters in there, which are invisible (or not, depending on your console settings). Replacing these out will make the string parseable:

$picDateTaken = $picDateTaken -replace "\u200e|\u200f", ""

Replacing control characters in general would be more involved, and I'm not sure if there isn't a better/more general way to get the metadata in an invariant format, but as long as you know exactly what you're dealing with this is good enough.

Upvotes: 3

Related Questions