Steven Weyhrich's Script: ApplesScript to batch change date of scanned photos based on filename

by: 
Last modified: May 29, 2020 2:01 AM
2 1838 Last modified May 29, 2020 2:01 AM

This user tipp has been moved to

Steven Weyhrich's Script: ApplesScript to batch change date of scanned photos based on filename - reformatted


------------------- deprecated code, because of formatting errors cased by the software update.



deprecated, because of formatting problems, that are corrupting the code (missing spaces and siilar).

Steven Weyhrich posted this script in the Photos for Mac Forum:

I have many photos to scan out of albums and boxes, and want them to display in Photos with the correct date. It is tedious to use Adjust Date and Time on every individual photo.

I had a similar script back in the iPhoto days, but did not have it for Photos, which uses different methods in scripting. Here is my first attempt at a script, and it works well for me. The explanations on how to use it are in the text of the AppleScript.Note that this is localized for the US and for English; I welcome any changes to make it work universally for other languages or regions. Copy and paste all the code between the dashes into Script Editor to run it. Has been tested with Photos 4.0 and Mac OS X 10.14.1 (Mojave).

Also note that I have included testing to limit years for these photos to be between 1800 and 2100 AD. If you have photos from earlier than 1800, you will have to adjust this in the code below. Similarly, if you are from the future and are running this in a virtual environment, you may have to make adjustments for your dates past 2100.

-------------------------------------------------------------------------------- -------------------------------

(* ZONKER'S DATE FROM TITLE

-- version 1.0

Applescript to batch change the time of a folder of photos in Apple Photos,based on the title in the filename.

Modern cameras include date and time data in the picture file, and Apple Photosautomatically includes this information when importing the photos to those programs.

Scanning in old photos or slides, however, does not have this information present,so that picture of great-grandmother's wedding dress is NOT encoded as being from1910; instead, after scanning it in as a JPEG and importing it to Photos, the "date"of the photo is the day it was scanned.

Yes, the "Adjust Date and Time" option will let me correct those options for one ormore pictures, but when you've scanned in hundreds of pictures, it is a very slowprocess plugging in that metadata.

This script helps address that problem. The user needs to add the date to the beginningof the filename of the JPEG file, import it to Apple Photos, and then run this script. Itwill automatically extract the date info from the filename, put it into the date and timefields for that photo in Photos, and additionally put the description from the filenameinto the photo.

The filename should be encoded as follows:

19690716183000 Our Apollo 11 party!.jpg

The date for this sample photo is July 16, 1969 at 18:30:00 (6:30 pm), and the title of thepicture is "Our Apollo 11 party!"

******************************

TO USE THIS SCRIPT:

1) Create a top-level album in Apple Photos to use for this purpose (the default album name is "DateFix". It needs to be an album that is not inside of a folder in Photos.

2) Down in the scripting below, find this line:

set theAlbumName to "DateFix"

and change it if you want a different name for the album for this purpose.

3) Drag the photo files that have been scanned and date-encoded in the filename from the Finder into that album.

4) Run this script.

5) If you save this script as an Application you can add it to the Dock and run it from there.


This script has been tested in Photos version 4.0, with MacOS X 10.14.1 (Mojave)

Some code borrowed from:

Joe Mailer's iPhoto ApplesScripts:http://joemaller.com/iphoto/

and

léonie's "Batch Change the Date and Time to a Fixed Date"https://discussions.apple.com/docs/DOC-8421

-- 2018 Steven Weyhrich-- licensed under Creative Commons Attribution Non Commercial ShareAlike 2.0-- http://creativecommons.org/licenses/by-nc-sa/2.0/

*)

-- initialize some variablesset startTime to current date

set theAlbumName to "DateFix" -- Hard code the name of the top-level album to scan and rename-- zero these outset imageSel to {}set aTitle to ""set aYear to ""set aMonth to ""set aDay to ""set aHour to ""set aMinutes to ""set aSeconds to ""

tell application "Photos"

activate


--Check to see if the Album with photos to be changed exists try if existscontainertheAlbumName then set thePhotosBuffer to containertheAlbumName set imageSel to every media item of thePhotosBuffer else error theAlbumName return end if

on error errMsg number errNum display dialog zonker & "Album '" & errMsg & "' does not exist" & return & return & "(AppleScript error " & errNum & ")" return end try

-- Okay, the album exists

display dialog Zonker's Batch Date From Title" & return & return & "••• Preparing to process date and time •••" & return & "••• on " & (count of imageSel) & " photos in the " & theAlbumName & " folder •••"


-- Now, loop through each subsequent image until COUNT is reached

repeat with i from 1 to count of imageSel

set thePhoto to itemi of imageSel

-- Format of date in title is: -- "20070810140512 Title" -- which means August 10, 2007, 2:05:12 pm

-- get filename of photo set aTitle to filename of thePhoto

-- Characters 1 - 14 of the filename are the encoded date string -- Character 15 should be a blank -- Characters 16 through the file extension are for the title/name/description of the photo

-- this flips the filename around in a temp variable set tmpFileName to (the reverse of every character of aTitle) as string -- this counts letters in the filename and then subtracts the count of the extension set myLength to (length of aTitle) - the (offset of "." in tmpFileName) -- This sets the name in Photos to the file name minus the extension (.jpg, .jpeg, .gif...etc) set aTitle to characters 1 thru myLength of aTitle as text

-- pad the end with two blanks if there is no text after the encoded date if myLength < 15 then set aTitle to aTitle & " "

-- Check to see if filename contains a valid encoded date set dateCode to characters 1 thru 14 of aTitle as string

-- see if dateCode is really a number set validNumber to false try set datenumb to dateCode as number set validNumber to true end try

if not validNumber then my errorTerm(aTitle, "Some of the first 12 characters of the filename are not numbers") return end if

-- extract year from start of title set aYear to text 1 thru 4 of aTitle

-- is it a valid year between 1800 and 2100 ? set nYear to aYear as number if nYear < 1800 or nYear > 2100 then my errorTerm(aTitle, "'" & nYear & "' is an invalid year") return end if

-- extract month from start of title set aMonth to text 5 thru 6 of aTitle

-- is it a valid month from 1 to 12? set nMonth to aMonth as number if nMonth < 1 or nMonth > 12 then my errorTerm(aTitle, "'" & aMonth & "' is an invalid month number") return end if

-- extract day from start of title set aDay to text 7 thru 8 of aTitle

-- is it a valid day of the month, 1 to 31? set nDay to aDay as number if nDay < 1 or nDay > 31 then my errorTerm(aTitle, "'" & aDay & "' is an invalid day of the month") return end if

-- February is a special case, so check that first if nMonth = 2 then -- yup, it's February if nYear mod 4 = 0 and (nYear mod 100 ≠ 0 or nYear mod 400 = 0) then set febDay to 29 as number else set febDay to 28 as number end if

if nDay > febDay then my errorTerm(aTitle, "In " & nYear & ", the last day of February should not be greater than " & febDay) return end if end if

-- Check 30 day months if (nMonth = 4 or nMonth = 6 or nMonth = 9 or nMonth = 11) and nDay > 30 then my errorTerm(aTitle, nMonth & "th month cannot have 31 days") return end if

-- If we got here, the day of month was valid

-- extract hour from start of aTitle set aHour to text 9 thru 10 of aTitle set nHour to aHour as number if nHour < 1 or nHour > 23 then my errorTerm(aTitle, "'" & nHour & "' is an invalid hour") return end if

-- extract minutes from start of aTitle set aMinutes to text 11 thru 12 of aTitle set nMinutes to aMinutes as number if nMinutes < 0 or nMinutes > 59 then my errorTerm(aTitle, "'" & nMinutes & "' is an invalid minute") return end if

-- extract seconds from start of aTitle set aSeconds to text 13 thru 14 of aTitle set nSeconds to aSeconds as number if nSeconds < 0 or nSeconds > 59 then my errorTerm(aTitle, "'" & nSeconds & "' is an invalid second") return end if

-- Okay, if we got here, all of the date and time digits are valid

-- create EXIF style of date string set tempDate to aYear & " " & aMonth & " " & aDay & " " & aHour & ":" & aMinutes & ":" & aSeconds

-- create correct date string for this program set newDate to my EXIFDateDecode(tempDate)

-- change the date for this photo set date of thePhoto to newDate

-- remove date from title -- (Note that if original filename did NOT have a title, the title will now be a single blank) set newTitle to characters 16 thru -1 of aTitle as string

-- change the title of his photo set the name of thePhoto to newTitle as text

end repeat

-- calculate how long this has taken set elapsedSeconds to ((current date) - startTime) -- display that info my updateReport(zonker, countimageSel, elapsedSeconds)

end tellreturn

on EXIFDateDecode(PhotoDate) -- converts EXIF dates into AppleScript Date objects

-- original subroutine by Joe Maller <http://www.joemaller.com>, for iPhoto

-- authored March 2005

-- licensed under Creative Commons Attribution Non Commercial ShareAlike 2.0

-- http://creativecommons.org/licenses/by-nc-sa/2.0/


-- 1.1 Added a month key to workaround an ambiguity problem with some international date formats

-- 1.2 (May 2005) removed any English language dependencies from date rebuilding

-- 1.3 (May 2005) rebuilt date extraction for compatibility with older versions of Applescript

-- 1.5 (January 2006) Adapted for iPhoto 6, now checks to see if PhotoDate is a date

if class of PhotoDate is date then return PhotoDate


-- EXIF dates are always #### ## ## ##:##:## [-####], extract characters to desired places, translate months to words if length of PhotoDate < 19 then return false-- fail on too short a supplied date else set monthList to {January, February, March, April, May, June, July, August, September, October, November, December} -- month constants, seems work internationally set theDate to "1/1/1 2:2:2" -- save a call to "current date" set theDate to datetheDate set month of theDate to item (text 6 thru 7 of PhotoDate) of monthList --if month < "01" then return false --if month > "12" then return false set day of theDate to text 9 thru 10 of PhotoDate set year of theDate to text 1 thru 4 of PhotoDate set time of theDate to ((text 12 thru 13 of PhotoDate) * hours + (text 15 thru 16 of PhotoDate) * minutes + (text 18 thru 19 of PhotoDate)) return theDate end ifend EXIFDateDecode

on errorTerm(fileTitle, msg) set zonker to "Zonker's Batch Date From Title" & return & return

beep

beep

beep display dialog zonker & "filename '" & fileTitle & "' does not contain valid date information." & return & return & "(" & msg & ")" with icon 1 returnend errorTerm

on secondsToHMS(theSeconds)

-- returns value of seconds in hours, minutes and seconds

set theHours to theSeconds div 3600 set theMinutes to theSeconds div 60 mod 60 set theSeconds to theSeconds mod 60

set outString to "" if theHours > 0 then set s to " " if theHours is not 1 then set s to "s " set outString to outString & theHours & " hour" & s end if if theMinutes > 0 then set s to " " if theMinutes is not 1 then set s to "s " set outString to outString & theMinutes & " minute" & s end if if theSeconds > 0 then set s to " " if theSeconds is not 1 then set s to "s" set outString to outString & theSeconds & " second" & s & "." end if return outStringend secondsToHMS

on updateReport(zonker, totalImages, processingTime)

if totalImages is 1 then set ddText to ("The date of the selected photo was changed based on the date in its title." & return) else set ddText to ("The " & totalImages & " selected photos' dates were changed based on the date in their titles." & return) end if

display dialog "Zonker's Batch Date From Title" & return & return & ddText & return & "Total processing time was " & my secondsToHMS(processingTime)

return

end updateReport

-------------------------------------------------------------------------------- -------------------------------



This user tip was generated from the following discussion: ApplesScript to batch change date of scanned photos based on filename

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.