Fixing Date Taken for Photos

I was able to figure out a few commands for exiftool in order to fix some photos that didn't have any useful date/time stamps for when they were taken. Here's the test I conducted:

# run this command to view the exif data (everything!)
exiftool.exe path/to/file.jpg

# view only the timestamps present in the exif data, note
# DateTimeOriginal is missing
exiftool.exe -a -G -time:all path/to/file.jpg

# [File]     File Modification Date/Time    : 2020:09:03 15:33:04-04:00
# [File]     File Access Date/Time          : 2023:10:14 17:58:19-04:00
# [File]     File Creation Date/Time        : 2023:10:14 17:49:34-04:00
# [ICC_Profile] Profile Date Time           : 2017:07:07 13:22:32

In the output above, the ICC_Profile should be ignored. The important fields are the Access & Creation date, which are going to be relative to the time that the file was copied to its current location, or in some cases, opened and viewed with certain programs. This is a problem because we don't want that date, it's irrelevant. We need to get DateTimeOriginal set in the file for a definitive "Date Taken" which we'll use to sort photos. The sensible option, when the DateTimeOriginal is missing and the "File Modification Date/Time" accurately reflects the date taken, is to set DateTimeOriginal to this modification date.

# this command does the update described above, preserving
# the original file as file.jpg_original in the same directory
exiftool.exe "-DateTimeOriginal<${FileModifyDate}" path/to/file.jpg

# now we can check it again
exiftool.exe -a -G -time:all path/to/file.jpg

# [File]          File Modification Date/Time     : 2023:10:14 17:59:48-04:00
# [File]          File Access Date/Time           : 2023:10:14 17:59:48-04:00
# [File]          File Creation Date/Time         : 2023:10:14 17:49:34-04:00
# [EXIF]          Date/Time Original              : 2020:09:03 15:33:04
# [ICC_Profile]   Profile Date Time               : 2017:07:07 13:22:32

This now has an EXIF entry for "Date/Time Original", which is what we want. It's worth nothing that File Modification Date/Time has been updated to reflect this change to the file's EXIF data. However, this is exactly what is desired because the "Date/Time Original" (or DateTimeOriginal) has the previous "File Modification Date/Time".

We can now run a script to test the file:

# test the original file
exiftool.exe -q -if "not $DateTimeOriginal" -r -p "$directory\$filename" path/to/file.jpg_original

# output:
# path/to/file.jpg_original
# Warning: [Minor] Tag 'DateTimeOriginal' not defined - path/to/file.jpg_original

# test the new file
exiftool.exe -q -if "not $DateTimeOriginal" -r -p "$directory\$filename" path/to/file.jpg

# outputs nothing because the DateTimeOriginal exists

This experiment demonstrates several details about this process, from identifying problematic files to fixing them, and then verifying the fix worked.

When working with exiftool, remember a few key things:

  • These commands are slightly different on Windows, Mac, and Linux. Beware!
  • By default, updating a file with exiftool preserves a copy of the original with a _original suffix.
  • There is a flag to directly edit the files without preserving the original, -overwrite_original_in_place.
  • The -r flag tells exiftool to recursively walk the given path and perform the respective task on each matching file it finds.

TL;DR One-Liner

The exiftool program is super powerful, and worthy of respect. Here's a one-liner that walks a path recursively looking for files missing a DateTimeOriginal field, and uses the file modified date to set DateTimeOriginal, overwriting the original file.

To help clarify the state before and after running the one-liner, an extra command is included to output all files that are missing DateTimeOriginal.

# for sanity, recursively walk & output files that will be changed
exiftool.exe -q -if "not $DateTimeOriginal" -r -p "$directory\$filename" path/to

# here's a one-liner to do it recursively
exiftool.exe -q -if "not $DateTimeOriginal" -r -overwrite_original_in_place -p "Setting DateTimeOriginal for: $directory/$filename" -d "%Y:%m:%d %H:%M:%S" "-DateTimeOriginal<${FileModifyDate}" path/to

# for sanity, see if any files still match
exiftool.exe -q -if "not $DateTimeOriginal" -r -p "$directory\$filename" path/to

Update responsibly!

Extra Credit

I spent some time looking into avoiding processing files with a prefix of ._ and came up with this:

exiftool.exe -q -if "not $FileName=~/\._.*/i and not $DateTimeOriginal" -r -p "$directory\$filename" path/to
Show Comments