Change Mod/Creation Date to folder path problem

G’day

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?

Brian

G’day Brian

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


G’day again

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. :confused:

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

Hi, Hank.

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.

Hi Nigel,

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.

Hi, Hank.

That seems to have done it. Works in both directions now.

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. :slight_smile:

I look forward to hours of picture re-date-stamping fun!

Brian

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.

Nigel,

This script seem to work nicely, but I get at error when any of the files have a name longer than 6 characters.

Thoughts?

Brian

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. :slight_smile:

Thanks again for the help!

Brian

That’s working nicely? :wink:

Only “Unghh?” :confused: The file I duplicated to test the script has a 22-character name. Do your names contain any unusual characters?

Harry,

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.

Brian

Fixed. I had to change the line NSError* error; to NSError* error = nil; and that fixed it. Crazy. Anyway we’re now at version 0.3! Get it here.

Works like a charm!

Thanks again,

Brian

Hi Hank,

the definition is necessary, whenever a variable is passed as an address pointer (&variable) and the called method does not definitely write into this variable