Search code examples
batch-filecmdexiftool

How to set file's DateTimeOriginal from file name using ExifTool


I have a directory with many image files that don't have their DateTimeOriginal metadata set, but do have this date in the file name itself in the format of YYYMMDD, e.g. 20120524_091536.mp4

I want to use exiftool to move these files into folders with the year and then sub-folders of the month (then later also set its DateTimeOriginal using this date from the filename).

Something like this:

exiftool -d "%Y-%m-%d" "-testname<D:\Pictures\${filename#;DateFmt('%Y')}\${filename#;DateFmt('%m')}\$FileName" "D:\Pictures\2012-05-24" -r 

But this gives an Error converting date/time for 'filename' error. Which makes sense, how do I tell it to format only the first 8 digits of the filename to a date?

The reason I want to use ExifTool for this, is that I actually am going to further refine this statement to only do this for files that don't already have a datetimeoriginal metadata set, so exiftool can filter these out...something like this qualifier:

exiftool '-datetimeoriginal<filemodifydate' -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00")) and ($filetype eq "JPEG")'

But instead of setting the datetimeoriginal to the filemodifydate, I need to set it to a date formatted from the filename.


Solution

  • To set DateTimeOriginal from the filename, the command is as simple as
    exiftool "-DateTimeOriginal<Filename" -if "not $datetimeoriginal or ($datetimeoriginal eq '0000:00:00 00:00:00')" -ext jpg DIR

    This is based upon Exiftool FAQ #5 which says "ExifTool is very flexible about the actual format of input date/time values when writing, and will attempt to reformat any values into the standard format unless the -n option is used. Any separators may be used (or in fact, none at all). The first 4 consecutive digits found in the value are interpreted as the year, then next 2 digits are the month, and so on."

    I removed the $filetype eq "JPEG" portion of your example and replaced it with the -ext option as checking against Filetype is a poor way to limit the files processed, as exiftool will still process and extract all metadata from every file to perform the check.

    Take note that the .mp4 filetype, as shown in your example, cannot hold the DateTimeOriginal tag. Instead, you'll have to use something like CreateDate. Also take note that exiftool has limited ability to write to video files.

    Because the filename isn't a timestamp type tag, you can't use the -d (dateformat) option as you discovered. Instead, you would have to use the Advanced formatting feature to split up the filename. Given the first example filename, your command would be:

    exiftool "-testname<D:\Pictures\${filename;s/^(\d{4}).*/$1/}\${filename;s/^\d{4}(\d\d).*/$1/}\%F" "D:\Pictures\2012-05-24" -r

    The -d "%Y-%m-%d" part is removed as it wasn't used in your example. ${filename;s/^(\d{4}).*/$1/} uses regex to match the first four digits of the filename and strip the rest. ${filename;s/^\d{4}(\d\d).*/$1/} strips the first four digits, matches the next two, and strips the rest of the filename. %F is an exiftool variable for the filename+ext used for the various exiftool file operations such as renaming and moving (but not available in tag processing).