AppleScript updating photo dates, with off-by-one hour bug

applescriptphotos

I’m scripting Photos to update the dates on photos in an album, to make them match the order of photos in the album. These are scans of old photos so the modification dates don’t match when the photos were taken anyway.

It almost works but some photos get a date one hour too early. That looks like a time zone problem except that the photos have no location information, so I can’t tell where it would come from.

tell application "Photos"
    set currentAlbum to album named "Album name"
    -- Start with a date slightly in the past, based on the album size.
    set currentAlbumCount to (count of media items in currentAlbum)
    set photoDate to (current date) - currentAlbumCount
    repeat with currentItem in media items in currentAlbum
        set photoDate to photoDate + 1
        set date of currentItem to photoDate
    end repeat
end tell

After running this, the EXIF for photos has the time/date for some being an hour earlier than others– e.g. one at 4:16:13 pm, the next one at 3:16:14, then 4:16:15, with no apparent reason why some are off by an hour.

I’m trying to do this because when I export and use the photos in other places (like Google photos) they get sorted by date, and I want to preserve the sort order.

Best Answer

It seems that the problem is that Photos doesn't edit all EXIF date tags when the script above runs, and Google Photos looks at tags that Photos doesn't change. Photos doesn't seem to have any other options for editing dates so I had to dig deeper. As @CJK described in comments, EXIF dates are a bit of a mess so it's necessary to edit the EXIF directly.

I ended up exporting the album from Photos and writing a custom shell script to change the dates. I used @CJK's suggestion of exiftool. The script follows. If you don't understand it, don't use it, because it has no error checking.

#!/bin/bash

# First export photos from Photos.app to a directory.
# - Export as "sequential". Use a prefix with no spaces.
# - Filenames should look like "Photo - 13.jpg"

TARGET_DIR="Your directory here"
# Count files. The sed on the end is because wc has pesky whitespace that causes trouble setting TIMESTAMP.
PHOTO_COUNT=`ls "$TARGET_DIR" | wc -l | sed 's/ //g'`

# Starting timestamp is slightly in the past, based on the number of photos.
let TIMESTAMP=`date +"%s"`-$PHOTO_COUNT

# Set IFS so that the loop will work properly with filenames that contain spaces.
IFS=$(echo -en "\n\b")

# Sort files numerically by the number in the filename
for FILE in `ls "$TARGET_DIR" | sort -n -k 3`
do
    # Move the timestamp by one second for every photo
    let TIMESTAMP=$TIMESTAMP+1
    # Get various date and time strings for EXIF.
    DATE_TIME_STRING=`date -r $TIMESTAMP +"%Y-%m-%d %H:%M:%S"`
    DATE_STRING=`date -r $TIMESTAMP +"%Y-%m-%d"`
    TIME_STRING=`date -r $TIMESTAMP +"%H:%M:%S"`

    # Set a bunch of date and time values in the photo's EXIF. It might be necessary to add more depending on the photos but these do the job for now.
    EXIFTOOL_CMD="/usr/local/bin/exiftool -overwrite_original -DateCreated=\"$DATE_STRING\" -FileCreateDate=\"$DATE_TIME_STRING\" -TimeCreated=\"$TIME_STRING\" -DateTimeOriginal=\"$DATE_TIME_STRING\" -CreateDate=\"$DATE_TIME_STRING\" -ModifyDate=\"$DATE_TIME_STRING\" -DigitalCreationDate=\"$DATE_STRING\" -DigitalCreationTime=\"$TIME_STRING\" \"$TARGET_DIR/$FILE\""
    eval $EXIFTOOL_CMD
done

A few notes:

  • exiftool has an AllDates option, but changing it doesn't actually change all dates.
  • I'm setting dates and times for numerous date/time related tags, but I found those by trial and error. They work for the photos I'm working with but may not be complete.

I tried using Image Events with AppleScript but it would only read the dates, not change them. Or so it seemed-- if someone knows different then I'd love to see a script that worked.