Change File's Modification Date To Parsed File Name

Hi all.

I need to set the modification dates of every file in a folder to the date/time in each file name, which are these two middle values (i.e. 2021-03-11 23:48:05).

Note that the text at the front varies, so we can’t just count the number of chars from the beginning, but rather from the first “|” separator.

Back Door | 2021-03-11 | 23_48_05 | 00_14

Any help with an Applescript to achieve this would be great.

One method to parse the date and time are text item delimiters, as shown below. Then you just loop through the files and use the Finder to set the modification date/time of the file.

set theString to "Back Door | 2021-03-11 | 23_48_05 | 00_14"

set ATID to AppleScript's text item delimiters

set AppleScript's text item delimiters to {" | "}
set {theDate, theTime} to {text item 2, text item 3} of theString

set AppleScript's text item delimiters to {"-"}
set {theYear, theMonth, theDay} to {text item 1, text item 2, text item 3} of theDate

set AppleScript's text item delimiters to {"_"}
set {theHour, theMinutes, theSeconds} to {text item 1, text item 2, text item 3} of theTime

set justToTest to theYear & space & theMonth & space & theDay & space & theHour & space & theMinutes & space & theSeconds

set AppleScript's text item delimiters to ATID

BTW, the above may seem a bit involved but it only takes about 4 milliseconds to execute.

Thanks for that, but could you help me with the other part, “Then you just loop through the files and use the Finder to set the modification date/time of the file.” since I have no idea how to do that?

FYI the folder’s name is “Videos” and it is on the Desktop.

Thanks so much,

Try the following to see if it works as you want. I tested it on multiple files and it worked fine.

The method used in the last line of the parseString handler to construct the date is not localized and in all likelihood will need to be changed. This is something I need to spend some time learning, and perhaps another forum member will have a suggestion in this regard.

set theFolder to (path to desktop as text) & "Videos"

tell application "Finder"
	set theFiles to every file in folder theFolder
	repeat with aFile in theFiles
		set fileName to name of aFile
		try
			set fileDate to parseString(fileName) of me
		on error
			display alert "A file does not contain the necessary date/time information" message fileName
			error number -128
		end try
		set modification date of aFile to fileDate
	end repeat
end tell

on parseString(theString)
	set ATID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {" | "}
	set {theDate, theTime} to {text item 2, text item 3} of theString
	set AppleScript's text item delimiters to {"-"}
	set {theYear, theMonth, theDay} to {text item 1, text item 2, text item 3} of theDate
	set AppleScript's text item delimiters to {"_"}
	set {theHour, theMinutes, theSeconds} to {text item 1, text item 2, text item 3} of theTime
	set AppleScript's text item delimiters to ATID
	return date (theMonth & "/" & theDay & "/" & theYear & " " & theHour & ":" & theMinutes & ":" & theSeconds)
end parseString

That didn’t work. it set all the files to the same date of Thursday, March 11, 2021 at 12:00:00 AM

  1. It is better to note create date objects using text representation, to avoid many localizating problems
  2. Setting modification date should be before on error statement:
  3. You can to not throw the error, as well. Continue the script for rest of files
set theFolder to (path to desktop as text) & "Videos"

tell application "Finder"
	set theFiles to every file in folder theFolder
	repeat with aFile in theFiles
		set fileName to name of aFile
		try
			set fileDate to parseString(fileName) of me
			set modification date of aFile to fileDate
		on error
			display alert "A file does not contain the necessary date/time information" message fileName giving up after 1
		end try
	end repeat
end tell

on parseString(theString)
	set theDateObject to (current date) -- create new local date object, using existing local date object
	set ATID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {" | "}
	set {theDate, theTime} to {text item 2, text item 3} of theString
	set AppleScript's text item delimiters to {"-"}
	set {theYear, theMonth, theDay} to {text item 1, text item 2, text item 3} of theDate
	set AppleScript's text item delimiters to {"_"}
	set {theHour, theMinutes, theSeconds} to {text item 1, text item 2, text item 3} of theTime
	set AppleScript's text item delimiters to ATID
	tell theDateObject
		set {its month, its day, its year} to {theMonth, theDay, theYear}
		set {its hours, its minutes, its seconds} to {theHour, theMinutes, theSeconds}
	end tell
	return theDateObject
end parseString

This did not work either, throwing the following error: A file does not contain the necessary date/time information, when the file are correctly situated inside a folder named “Videos” on the Desktop.

KniazidisR. Your approach is an excellent one. Except as noted below, it worked great with several test files.

My script already used theDate as a variable and you used this variable to create the date object. After giving the date object a different variable name, everything worked great.

Removing the error checking then shows the real issue: “Can’t set month of “2021-03-11” to “03”.”

I can’t get either script to work :frowning:

OK, followed that advice and rename the variable and it works. Thanks!

But how would I also be able to change the creation date to the same as the modification date? What would we need to add to this script?

The following changes both the creation and modification dates in my testing. The entire script should probably be rewritten to better utilize ASObjC but that’s not worth the time and effort at this point.

use framework "Foundation"
use scripting additions

set theFolder to ((path to desktop as text) & "Videos") as alias

tell application "Finder"
	set theFiles to every file in folder theFolder as alias list
	repeat with aFile in theFiles
		set fileName to name of aFile
		try
			set fileDate to parseString(fileName) of me
			changeDates(fileDate, aFile) of me
		on error
			display alert "A file does not contain the necessary date/time information" message fileName
		end try
	end repeat
end tell

on parseString(theString)
	set theDateObject to (current date) -- create new local date object, using existing local date object
	set ATID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {" | "}
	set {theDate, theTime} to {text item 2, text item 3} of theString
	set AppleScript's text item delimiters to {"-"}
	set {theYear, theMonth, theDay} to {text item 1, text item 2, text item 3} of theDate
	set AppleScript's text item delimiters to {"_"}
	set {theHour, theMinutes, theSeconds} to {text item 1, text item 2, text item 3} of theTime
	set AppleScript's text item delimiters to ATID
	tell theDateObject
		set {its month, its day, its year} to {theMonth, theDay, theYear}
		set {its hours, its minutes, its seconds} to {theHour, theMinutes, theSeconds}
	end tell
	return theDateObject
end parseString

on changeDates(theASDate, aFile)
	set theNSDate to current application's NSDate's dateWithTimeInterval:0.0 sinceDate:theASDate
	set theURL to current application's |NSURL|'s fileURLWithPath:(POSIX path of aFile)
	theURL's setResourceValue:theNSDate forKey:(current application's NSURLContentModificationDateKey) |error|:(reference)
	theURL's setResourceValue:theNSDate forKey:(current application's NSURLCreationDateKey) |error|:(reference)
end changeDates

Agreed, but anyway…

use AppleScript version "2.5" -- 10.11 or later
use framework "Foundation"
use scripting additions

-- prepare date formatter and keys
set df to current application's NSDateFormatter's new()
df's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"US-Posix")
df's setDateFormat:"yyyy-MM-dd | HH_mm_ss"
set modDateKey to current application's NSURLContentModificationDateKey
set creationDateKey to current application's NSURLCreationDateKey

set theFolder to ((path to desktop as text) & "Videos") as alias
set theURLs to current application's NSFileManager's defaultManager()'s contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
repeat with theURL in theURLs
	set theName to theURL's lastPathComponent()
	set theRange to (theName's rangeOfString:" | ")
	if |length| of theRange > 0 then
		set dateString to (theName's substringWithRange:{(theRange's location) + 3, 20})
		set theDate to (df's dateFromString:dateString)
		(theURL's setResourceValue:theDate forKey:modDateKey |error|:(reference))
		(theURL's setResourceValue:theDate forKey:creationDateKey |error|:(reference))
	end if
end repeat

You are right, Peavine. Now I have fixed the error there (post #6).

I tried changing Creation Date using plain AppleScript, without third party utilities. When the script changes the Modification Date to a date earlier than the original Creation Date, Finder automatically changes the Creation Date itself.

So the problem is about changing the Creation Date when the Modification Date changes to a date later than the original Creation Date. I have not been able to solve the problem using plain AppleScript. Although it is not clear to me in what real case this might be needed.

@Shane. Thanks for the script, which works great. I tried but was unable to directly create and set the values of an NSDate from a string for use in setting file dates, and I resorted to a workaround, which bridged an ASDate to an NSDate. Your script provides a simple method that avoids this workaround.

@KniazidisR. It doesn’t make sense to me either why users of basic AppleScript can change the creation date in one direction (by changing the modification date) but not the other. Perhaps the Apple software engineers prefer that users not change the creation date but didn’t want to allow a situation where the modification date could precede the creation date. Fortunately, we now have a simple ASObjC solution.