Change file creation date based on file name?

I use a program called Beyond Compare (Scooter Software - Home of Beyond Compare) pretty extensively. I also make backups of its settings/sessions as things change using Automator (see screenshot).

Here’s the issue I’m trying to solve. In the second screenshot you’ll see that although the archive date is 2024/06/25, the created date is August 26, 2022 and the modified date is April 27, 2024. So, prior to using an AppleScript to purge any of the Beyond Compare settings/sessions archives, I’d need to change the created/modified dates to agree with when the archive was created.

I’ve done some reading here and this particular discussion seems like the script in Post 2 by regulus6633 could be modified for what I want to do, although there’s an issue. The post has a link to a command line utility called “ChangeFileDates”, which is no longer valid. Looking to see if it’s still available somewhere, and, if anyone knows if it will work with Monterey 12.7.5.

Homer712. If an ASObjC solution is OK, I’ve included my suggestion below. However, you can’t use a slash to separate date values in a file name–I used a dot in the following. Perhaps I don’t understand where the date is gotten from?

use framework "Foundation"
use scripting additions

set theFile to POSIX path of (choose file)
try
	set theDate to getDate(theFile)
on error
	display dialog "A date was not found in the file name" buttons {"OK"} cancel button 1 default button 1
end try
changeDate(theFile, theDate)

on getDate(theString)
	set theString to current application's NSString's stringWithString:theString
	set thePattern to "\\d{4}\\.\\d{1,2}\\.\\d{1,2}"
	set theRange to theString's rangeOfString:thePattern options:1024
	set patternMatch to (theString's substringWithRange:theRange)
	return patternMatch as text
end getDate

on changeDate(theFile, theDate)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	set dateFormatter to current application's NSDateFormatter's new()
	dateFormatter's setDateFormat:"yyyy.MM.dd"
	set theDate to (dateFormatter's dateFromString:theDate)
	(theFile's setResourceValue:theDate forKey:(current application's NSURLContentModificationDateKey) |error|:(reference))
	(theFile's setResourceValue:theDate forKey:(current application's NSURLCreationDateKey) |error|:(reference))
end changeDate

peavine, can’t thank you enough, works perfectly! The date format (xxxx/x/xx) comes from when I created the Automator script, and should be easy enough to change to (xxxx.x.xx). Changed the date on one of the archives to 2023.8.27, ran the script and it changed both the created and modified dates to August 8, 2023.

Many thanks for always coming up with solutions for me to try, no matter how convoluted my questions may seem. Again, thanks!

Well, spoke too soon. Your script is still functioning perfectly, the issue is Automator, it doesn’t have an option for using dots in the date format. It’s a Forward Slash, a Dash, or None.

I don’t know how to get the script to work with a forward slash, but a dash or none is easily done. Let me know which you prefer, and I’ll edit my script. However, if the answer is none, months and days in the source file name would almost have to be zero-padded (e.g. 20240627).

BTW, just in general, it might be best to require that the months and days be zero-padded. Would this be an issue?

Let’s go with a Dash, and I’m already using the zero. So Automator will spit out the file, with archive, date, then extension. Example, today’s date would look like this: BCSessions Archive 2023-08-27.bcpkg

I’ve made those changes in the following script.

use framework "Foundation"
use scripting additions

set theFile to POSIX path of (choose file)
try
	set theDate to getDate(theFile)
on error
	display dialog "A date was not found in the file name" buttons {"OK"} cancel button 1 default button 1
end try
changeDate(theFile, theDate)

on getDate(theString)
	set theString to current application's NSString's stringWithString:theString
	set thePattern to "\\d{4}-\\d{2}-\\d{2}"
	set theRange to theString's rangeOfString:thePattern options:1024 --option 1024 is regex
	return (theString's substringWithRange:theRange)
end getDate

on changeDate(theFile, theDate)
	set theFile to current application's |NSURL|'s fileURLWithPath:theFile
	set dateFormatter to current application's NSDateFormatter's new()
	dateFormatter's setDateFormat:"yyyy-MM-dd"
	set theDate to (dateFormatter's dateFromString:theDate)
	(theFile's setResourceValue:theDate forKey:(current application's NSURLContentModificationDateKey) |error|:(reference))
	(theFile's setResourceValue:theDate forKey:(current application's NSURLCreationDateKey) |error|:(reference))
end changeDate

Working perfectly with dates reformatted with dashes between the numbers, thank you.

1 Like

I’ve been trying (unsuccessfully) to make one modification to the script. The files I need to change are always in the same, exact folder. So, rather than the (choose file) I’ve tried adding a path to that folder which is “/Users/homer/Documents/MacBook Pro Specific/Beyond Compare/Beyond Compare Backups”. Can you give me a hint how I could get this done. Thanks.

The correct file path needs a leading tilde:
“~/Users/homer/Documents/MacBook Pro Specific/Beyond Compare/Beyond Compare Backups”

I think the issue I’m having is because while I’m trying to direct the script to a specific folder, the script itself is looking for a specific file. I’m going to try to possibly have a separate script that first gets me to the Beyond Compare Backups folder, then run the script that pevine provided.

Do I understand correctly that you want the script to iterate through every file in the specified folder and to change their creation and modification dates if their file names contain a date? This is not difficult to do, but I wanted to check first.

That’s exactly what I’m attempting to do, you read my mind.

Homer712. The script included below should do what you want. Files that do not have a properly-formatted date in their names are skipped. At the beginning of the script, you will need to set the target folder and the extension of the files that will be modified (presumably bcpkg). Let me know if setting the file extension is an issue (e.g. perhaps there are more than one).

use framework "Foundation"
use scripting additions

set theFolder to "/Users/Robert/Downloads/" --set to desired value
set theExtension to "txt" --set to desired value
set theFiles to getFiles(theFolder, theExtension)

repeat with aFile in theFiles
	try
		set theDate to getDate(aFile)
		changeDate(aFile, theDate)
	end try
end repeat

on getFiles(theFolder, theExtension)
	set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
	set fileManager to current application's NSFileManager's defaultManager()
	set folderContents to fileManager's contentsOfDirectoryAtURL:(theFolder) includingPropertiesForKeys:{} options:4 |error|:(missing value)
	set thePredicate to current application's NSPredicate's predicateWithFormat_("pathExtension ==[c] %@", theExtension)
	set theFiles to (folderContents's filteredArrayUsingPredicate:thePredicate)
end getFiles

on getDate(theFile)
	set theString to theFile's |path|()
	set theString to current application's NSString's stringWithString:theString
	set thePattern to "\\d{4}-\\d{2}-\\d{2}"
	set theRange to theString's rangeOfString:thePattern options:1024 --option 1024 is regex
	return (theString's substringWithRange:theRange)
end getDate

on changeDate(theFile, theDate)
	set dateFormatter to current application's NSDateFormatter's new()
	dateFormatter's setDateFormat:"yyyy-MM-dd"
	set theDate to (dateFormatter's dateFromString:theDate)
	(theFile's setResourceValue:theDate forKey:(current application's NSURLContentModificationDateKey) |error|:(reference))
	(theFile's setResourceValue:theDate forKey:(current application's NSURLCreationDateKey) |error|:(reference))
end changeDate

You know, I try to put together a few scripts from bits and pieces I find here and a couple of other sites, some work, some don’t, and I’ll spend the time to try to learn and figure things out. But, the things you put together here, at least to me, are nothing short of magical. Changed the folder’s location path, changed the file extension to “bcpkg” and the script functions perfectly. Thank you!

1 Like

Nope, /Users/... is the correct form in this case.

I guess what you meant is ~/Documents, which is also correct.

Not sure this is possible, so I’ll post the question. I have the following script that will look at the “Beyond Compare Backups” folder and delete any files that are over 90 days old.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "Finder"
	try
		set theFolderAlias to alias "Users:homer:Documents:MacBook Pro Specific:Beyond Compare:Beyond Compare Backups:"
		delete (get items of theFolderAlias whose creation date < ((current date) - 90 * days))
	on error
		display dialog "Beyond Compare Backups Folder is Missing"
	end try
end tell

And what I just though of is that there may be a time when that 90 days will cover all the files in that folder, and I’d be left with no backups. So, is it possible to modify the script so that it deletes all files older that 90 days, but always keeps at least three (3) of the newest ones, even though they fall into that 90 range?

Think I’ve got the issue above figured out. I’m able to run three scripts in sequence, in which the first one does a backup, the second (by pevine a few posts above) changes the created/modified date, and finally the third one (which I posted above) deletes backups from the folder that are over 90 days old. Works very well and there will always be at least one backup archive remaining. Problem solved.