I have organized all my photos in folders by date. Root folder is year, next folder month, next folder day.
2009
01
10
12
02
22
ETC.
Over the years many the EXIF and creation dates have been changed or corrupted. I wrote this script to change the Mod and Creation dates to the folder structure the file is in. I then use ‘Better Finder Attributes’ to copy the creation date to the EXIF date. All of this works pretty well, but I can only do one folder at a time.
Can anybody help me with making this work with multiple folders?
I would like to process and entire year or month at least. It is pretty time consuming right now.
Also, ChangeFileDates works well, but it would be nice if I could find a way to do the EXIF dates directly.
Thanks
-- this will change the creation and modification dates of a chosen file
-- http://www.hamsoftengineering.com/codeSharing/ChangeFileDates/ChangeFileDates.html
on open files_to_add
set changeFileDatesPath to (path to home folder as text) & "UnixBins:ChangeFileDates"
repeat with fileA in files_to_add
tell application "Finder"
tell file fileA
set od to AppleScript's text item delimiters
set File_Path to POSIX path of fileA
set file_ to POSIX path of fileA
set AppleScript's text item delimiters to {"/"}
set folder_day to -2th text item of File_Path
set folder_month to -3th text item of File_Path
set folder_year to -4th text item of File_Path
set createddate to creation date as text
set AppleScript's text item delimiters to {" "}
set createdtime to -2th text item of createddate
set creationdate to folder_month & "/" & folder_day & "/" & folder_year & " " & createdtime
set AppleScript's text item delimiters to od
try
do shell script quoted form of POSIX path of changeFileDatesPath & " -mDate " & quoted form of creationdate & " -cDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
do shell script quoted form of POSIX path of changeFileDatesPath & " -cDate " & quoted form of creationdate & " -mDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
end try
end tell
end tell
end repeat
end open
Build a list of files. As long as you always have each file buries 3 folders deep, and only in the correctly numbered folders, something like this should do the trick.
Regards
Santa
tell application "Finder"
set changeFileDatesPath to (path to home folder) & "UnixBins:ChangeFileDates" as text as alias
with timeout of 600 seconds --< should not really be necessary
set files_to_add to files of (entire contents of changeFileDatesPath) as alias list
end timeout
repeat with fileA in files_to_add
tell file fileA
set od to AppleScript's text item delimiters
set File_Path to POSIX path of fileA
set file_ to POSIX path of fileA
set AppleScript's text item delimiters to {"/"}
set folder_day to -2th text item of File_Path
set folder_month to -3th text item of File_Path
set folder_year to -4th text item of File_Path
set createddate to creation date as text
set AppleScript's text item delimiters to {" "}
set createdtime to -2th text item of createddate
set creationdate to folder_month & "/" & folder_day & "/" & folder_year & " " & createdtime
set AppleScript's text item delimiters to od
try
do shell script quoted form of POSIX path of changeFileDatesPath & " -mDate " & quoted form of creationdate & " -cDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
do shell script quoted form of POSIX path of changeFileDatesPath & " -cDate " & quoted form of creationdate & " -mDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
end try
end tell
end repeat
end tell
The ‘ChangeFileDatePath’ is the path to the binary for the program that actually does the date changing, it isn’t the path to the files I want to change.
I had an “on open files_to_add” at the beginning so I could drag files onto the applet. I tried adding the alias list to files_to_add, but I think I may need another variable.
Thank you for the help . . . . any suggestions on how to proceed?
This should do it. Saved as an App, and drop the folder on it.
I’ve added a basic test-for-date-year routine as well.
Just out of interest, why are you executing 2 shell scripts that basically do the same thing?
Regards
Santa
on open The_Folder
tell application "Finder"
set changeFileDatesPath to ((path to home folder) & "UnixBins:ChangeFileDates") as text
with timeout of 600 seconds --< should not really be necessary
set files_to_add to (files of (entire contents of folder The_Folder)) as alias list
end timeout
repeat with x from 1 to (count of files_to_add)
set fileA to item x of files_to_add
tell file fileA
try
set od to AppleScript's text item delimiters
set File_Path to POSIX path of fileA
set file_ to POSIX path of fileA
set AppleScript's text item delimiters to {"/"}
set folder_day to -2th text item of File_Path
set folder_month to -3th text item of File_Path
set folder_year to -4th text item of File_Path
try
set Fixflag to ((folder_year as number) > 2000)
on error
set Fixflag to false
end try
set createddate to creation date as text
set AppleScript's text item delimiters to {" "}
set createdtime to -2th text item of createddate
set creationdate to folder_month & "/" & folder_day & "/" & folder_year & " " & createdtime
set AppleScript's text item delimiters to od
if Fixflag then
try
do shell script quoted form of POSIX path of changeFileDatesPath & " -mDate " & quoted form of creationdate & " -cDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
do shell script quoted form of POSIX path of changeFileDatesPath & " -cDate " & quoted form of creationdate & " -mDate " & quoted form of creationdate & " -file " & quoted form of POSIX path of fileA
end try
end if
on error
set AppleScript's text item delimiters to od
end try
end tell
end repeat
end tell
say "Finished"
end open
For those of you with Developer Tools installed, this script will do the same as the above, without the need for Brians special file ‘ChangeFileDates’.
Regards
Santa
on open The_Folder
tell application "Finder"
set changeFileDatesPath to ((path to home folder) & "UnixBins:ChangeFileDates") as text
with timeout of 600 seconds --< should not really be necessary
set files_to_add to (files of (entire contents of folder The_Folder)) as alias list
end timeout
repeat with x from 1 to (count of files_to_add)
set fileA to item x of files_to_add
tell file fileA
try
set od to AppleScript's text item delimiters
set File_Path to POSIX path of fileA
set file_ to POSIX path of fileA
set AppleScript's text item delimiters to {"/"}
set folder_day to -2th text item of File_Path
if (count of folder_day) as text < 10 then set folder_day to "0" & folder_day -- may not be necessary
set folder_month to -3th text item of File_Path
if (count of folder_month) as text < 10 then set folder_month to "0" & folder_month
set folder_year to -4th text item of File_Path
try
set Fixflag to ((folder_year as number) > 2000)
on error
set Fixflag to false
end try
set createddate to creation date as text
set AppleScript's text item delimiters to {" "}
set AppleScript's text item delimiters to od
set creationdate to folder_month & "/" & folder_day & "/" & folder_year
if Fixflag then
try
do shell script "/Developer/Tools/SetFile -d " & quoted form of creationdate & " -m " & quoted form of creationdate & " " & quoted form of POSIX path of fileA
on error errmsg
display dialog "FixFlag " & errmsg
end try
end if
on error errmsg
set AppleScript's text item delimiters to od
display dialog errmsg
end try
end tell
end repeat
end tell
say "Finished"
end open
The last script I posted does not seem to keep the individual times that a file is created. This fixes it.
on open The_Folder
tell application "Finder"
with timeout of 600 seconds --< should not really be necessary
set files_to_add to (files of (entire contents of folder The_Folder)) as alias list
end timeout
repeat with x from 1 to (count of files_to_add)
set fileA to item x of files_to_add
tell file fileA
try
set od to AppleScript's text item delimiters
set File_Path to POSIX path of fileA
set file_ to POSIX path of fileA
set AppleScript's text item delimiters to {"/"}
set folder_day to -2th text item of File_Path
if (count of folder_day) as text < 10 then set folder_day to "0" & folder_day -- may not be necessary
set folder_month to -3th text item of File_Path
if (count of folder_month) as text < 10 then set folder_month to "0" & folder_month
set folder_year to -4th text item of File_Path
try
set Fixflag to ((folder_year as number) > 2000)
on error
set Fixflag to false
end try
set createddate to creation date as text
set AppleScript's text item delimiters to {" "}
set createdtime to -2th text item of createddate
set createdAMPM to -1th text item of createddate
set AppleScript's text item delimiters to od
set creationdate to "(" & folder_month & "/" & folder_day & "/" & folder_year & " " & createdtime & " " & createdAMPM & ")"
if Fixflag then
try
do shell script "/Developer/Tools/SetFile -d " & quoted form of creationdate & " -m " & quoted form of creationdate & " " & quoted form of POSIX path of fileA
on error errmsg
display dialog "FixFlag " & errmsg
end try
end if
on error errmsg
set AppleScript's text item delimiters to od
display dialog errmsg
end try
end tell
end repeat
end tell
say "Finished"
end open
I think this does what’s needed, but I don’t have the ChangeFileDates program. The script assumes that you’ll only drop the appropriate files or folders (year, month, or day) onto it.
-- this will change the creation and modification dates of dropped files and/or the files in dropped folders,
-- assuming file paths ending "./yyyy/mm/dd/file name".
-- http://www.hamsoftengineering.com/codeSharing/ChangeFileDates/ChangeFileDates.html
on open dropped_items
set changeFileDatesPath to POSIX path of ((path to home folder as text) & "UnixBins:ChangeFileDates")
repeat with this_item in dropped_items
set this_POSIX to POSIX path of this_item
if (this_POSIX ends with "/") then
-- If this item's a folder, get the POSIX paths of all the visible files in it.
set these_POSICES to paragraphs of (do shell script "find -f " & (quoted form of text 1 thru -2 of this_POSIX) & " \\( -type f -and -not -path '*/.*' \\)")
-- Deal with each file individually.
repeat with this_POSIX in these_POSICES
handle_file(this_POSIX, changeFileDatesPath)
end repeat
else -- This dropped item's a file.
handle_file(this_POSIX, changeFileDatesPath)
end if
end repeat
end open
on handle_file(File_Path, changeFileDatesPath)
-- Arrange the relevant parts of the file path into a mm/dd/yyyy short date string.
-- It's assumed that the folder names will already be in yyyy, mm, and dd formats.
set od to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"/"}
set {folder_year, folder_month, folder_day} to text items -4 thru -2 of File_Path
set creationdate to {folder_month, folder_day, folder_year} as text
set AppleScript's text item delimiters to od
-- Get the file's creation date and format it in 24-hour time as hh:mm:ss
tell application "System Events" to set createdtime to time of (get creation date of file File_Path) -- System Events accepts POSIX paths in file specifiers.
tell (1000000 + createdtime div hours * 10000 + createdtime mod hours div minutes * 100 + createdtime mod minutes) as text
set createdtime to text 2 thru 3 & ":" & text 4 thru 5 & ":" & text 6 thru 7
end tell
set creationdate to quoted form of (creationdate & " " & createdtime)
-- Set the file's creation and modification dates to the above date and time.
do shell script (changeFileDatesPath & " -cDate " & creationdate & " -mDate " & creationdate & " -file " & quoted form of File_Path)
end handle_file
Edit 2011/02/01: Made the “find” shell script slightly less cryptic. Edit 2011/02/05: I spent an hour yesterday working out some “sed” hieroglyphics to replace six lines of AppleScript delimiter code which singled the double slashes returned in the “find” shell script result. This morning I’ve discovered that all that’s needed is to drop the end slash from this_POSIX before feeding it to “find”!
Now that I have downloaded “ChangeFileDates” and tried it with my script in the post above, I can see why Brian used two calls. “ChangeFileDates” needs to be executed twice to change the creation date, although it requires both parameters each time.
Hi everyone, I’m glad to see you getting use of my program. I’m the creator of ChangeFileDates. Can you explain this “I need to run it twice” problem? If I create a new TextEdit file, and then run the following script on it (the same one from my website) then both dates are set properly. So please explain where you think the problem might be because I don’t have a problem when I run it as explained. If you can show me the problem then maybe I can fix it.
-- this will change the creation and modification dates of a chosen file
set changeFileDatesPath to (path to home folder as text) & "UnixBins:ChangeFileDates" -- path to unix exe
set creationDate to "10/03/2008 04:28:10"
set modificationDate to "07/30/2009 14:49:00"
set aFile to choose file without invisibles
try
do shell script quoted form of POSIX path of changeFileDatesPath & " -cDate " & quoted form of creationDate & " -mDate " & quoted form of modificationDate & " -file " & quoted form of POSIX path of aFile
on error theError number errorNumber
display dialog "There was an error:" & return & theError & return & return & "Error Number: " & errorNumber as text buttons {"OK"} default button 1 with icon stop
end try
Your script works perfectly here! But when I run mine with other copies of the same file, only the modification date’s changed unless I run the script twice. The minimal testing I’ve done so far this evening suggests that the problem occurs when changing the creation date to a later one than the file already has. Changing it to an earlier one seems to work first time. Maybe the system has some built-in safeguard against having the modification date earlier than the creation date and it matters in which order they’re set.
You’re right. If the new creation date was later than the original modification date then the new creation date was not set to the file. So I updated the tool. It’s now version 0.2. I now set the mod date first in the tool and then set the creation date. Setting them one-at-a-time rather than at the same time takes care of the problem. Of course I set the mod date first.
Thanks for finding that bug. You can get the new tool here.
This is all fantastic. Thank you all for the excellent input, and thank you Hank for the excellent tool. I should have posted a bug directly with you, but I assumed it was something I was doing wrong.
If you could get it to change the EXIF date as well, that would save me a lot of time.
I look forward to hours of picture re-date-stamping fun!
No problem. Regarding the exif date that’s a whole different thing so it would require another tool. Fortunately there’s already tools for that. I use ExifTool. You can get it here. Good luck.
I tried EXIF tool, but it only shifts dates in EXIF, it doesn’t change them to known value. I think I would have to read the original date for each files then do the math for the date shift. I had troubles with my original script, let alone something that complicated.
I think I figured out my issue. If I use v.1 of ‘ChanegFileDates’ I have to run it twice if the date needs to be previous the existing date. But, if I run v.2 of ‘ChanegFileDates’ it will not let me effect file with names longer than 6 characters. If I put the year folder on the root level of the drive I can do files with names of 8 characters.
I tried using Nigels final script with the ‘ChanegFileDates’ duplicated on v.1 and it seems to work every time.