I’m writing an Applescript that will do (among many other things) the following:
get the modification date of a file
set the modification date (and creation date) of a different file to the modification date of the first file
(Among the other things that the script will do is convert the first file into a different format; I want to give the user the option of giving the converted version of the file the same date as the original version.)
I know how to get the modification date of a file:
set myFile to (choose file)
tell application "System Events" to set modDate to modification date of myFile
And I know how to use touch to set the date of a file (in this example, the date is set to 1999-January-1, 6:00 a.m.):
set modDate to "9901010600"
set newFile to (choose file)
do shell script "touch -t" & space & "'" & modDate & "'" & space & quoted form of POSIX path of newFile
But I cannot figure out how to coerce the modification date provided by System Events into the format required by the touch command.
After doing some more searching in this forum, I was able to put together this horrible mess of code (based in part on some elegant code by Yvan Koenig), but I’m certain that something more elegant must exist:
choose file
tell application "System Events" to set getDate to modification date of disk item (result as text)
set shortDate to text -2 thru -1 of (year of getDate as text) & text -2 thru -1 of ("00" & (month of getDate as number)) & text -2 thru -1 of ("00" & day of getDate)
set getTime to time string of getDate
if length of getTime is 10 then set getTime to "0" & getTime
set shortTime to text -11 thru -10 of getTime & text -8 thru -7 of getTime
if text -2 of getTime is "P" then set shortTime to (shortTime as number) + 1200
if shortTime is greater than 2400 then set shortTime to (shortTime as number) - 1200
set oldDate to shortDate & shortTime
Another option might be, that while you’re in unix anyway to format the date there. It might take me a while to remember how to do that, but if you do a lot of that, then it might be worth while looking into it.
set myFile to (choose file)
tell application "System Events" to set modDate to modification date of myFile
set {year:y, month:m, day:d, hours:hr, minutes:min, seconds:sec} to modDate
set modDate to (y * 10000 + m * 100 + d) as text
tell (1000000 + hr * 10000 + min * 100 + sec) as text to set modDate to modDate & text 2 thru 5 & "." & text 6 thru 7
FWIW, here’s an ASObjC-based library solution, which should be a bit faster because it avoids both System Events and the shell:
use framework "Foundation"
on updateModDateAtPath:POSIXPath toDateAtPath:sourcePOSIXPath
set theURL to current application's NSURL's fileURLWithPath:POSIXPath
set theOldURL to current application's NSURL's fileURLWithPath:sourcePOSIXPath
set whatWeWant to current application's NSURLContentModificationDateKey
set {theResult, theValue} to theOldURL's getResourceValue:(reference) forKey:whatWeWant |error|:(missing value)
theURL's setResourceValue:theValue forKey:whatWeWant |error|:(missing value)
end updateModDateAtPath:toDateAtPath:
And of course even if System Events (or the FInder) or the shell are used, the date formatting problem disappears if you stick with like-for-like. System Events and the Finder both understand AppleScript dates and ‘touch’ has an option for setting a file’s modification date to that of another.
As for changing a creation date, it can only be done (as far as I can see) by setting the file’s modification date to a date earlier than its current creation date. The creation date will then be set to that same value. So if you’ve just created a file and want it to have the same creation and modification dates as an already exisiting one, set its modification date to the earlier file’s creation date and then to its modification date. Obviously a special arrangment will be needed for the creation date if you’re using ‘touch’ to do the setting.
Exactly - I use the option in touch. Here is the code I used, taken from Nigel’s elegant example. CnvFile is the original file; newPath is the quoted form of the POSIX path of the converted file:
tell application "System Events" to set modDate to modification date of cnvFile
set {year:y, month:m, day:d, hours:hr, minutes:min, seconds:sec} to modDate
set modDate to (y * 10000 + m * 100 + d) as text
tell (1000000 + hr * 10000 + min * 100 + sec) as text to set modDate to modDate & text 2 thru 5 & "." & text 6 thru 7
try
do shell script "touch -t" & space & "'" & modDate & "'" & space & newPath
on error errMsg
activate
display dialog "Error setting date of converted file:" & return & return & errMsg
end try
Am I wrong ?
The original question was :
2. set the modification date (and creation date) of a different file to the modification date of the first file.
If I understand them well, the given answer set the modification dateTime and the access dateTime but don’t change the creation date.
For years I use a code borrowed to Nigel Garvey and, maybe because I’m tired, I don’t see why the one which he posted today is better than this old one :
set myFile to (choose file)
tell application "System Events" to set modDate to modification date of myFile
tell modDate to set formattedModDate to (((its year) * 10000 + (its month) * 100 + (its day)) as text) & text 2 thru -1 of ((1000000 + (its hours) * 10000 + (its minutes) * 100 + (its seconds)) as text)
Yvan KOENIG (VALLAURIS, France) samedi 6 septembre 2014 21:04:20
The original question was actually about how to format a date parameter for the ‘touch’ command. The script I posted yesterday is exactly the same as the one you’ve shown, except that it’s laid out slightly differently and inserts a period before the ‘seconds’ digits, as is required by ‘touch’.
In my second post (#9 above), I pointed out that for a modification date alone, it would be easier to use the same agent to set it as was used to get it from the reference file. There’d then be no need to reformat it. For instance, ‘touch’ has its own option for setting one file’s modification date to another’s. I’m not sure emendelson grasped what I meant:
do shell script "touch -r " & quoted form of posix path of referenceFile & space & quoted form of posix path of fileToTouch
This only changes the modification date, not the creation date ” unless the modification date set is earlier than the ‘touched’ file’s creation date, in which case the creation date too is changed to new modification date.
So, if the reference file’s older than the one to be ‘touched’ ” as it probably will be in emendelson’s scenario ” both its creation and modification dates can be applied to the ‘touched’ file by touching first with the creation date and then with the modification date. If the ‘touch’ command’s used to do the touching, some other means has to be used to get the creation date, which then needs to be reformatted for ‘touch’. With System Events or the Finder, it’s relatively straightforward:
tell application "System Events"
set {creation date:creaDate, modification date:modDate} to referenceFile
set fileToTouch's modification date to creaDate
set fileToTouch's modification date to modDate
end tell
You’re absolutely right: I didn’t understand what you were saying about the touch command, but now I do, and it’s even more elegant than your other (very elegant solution). I can’t thank you enough for this.
Clearly I was too tired.
(1) I missed the dot in the final date so I removed the underscore which was inserted in the code which I use daily.
(2) I missed the sentence about creation date in the message #9
Maybe it’s time to get retired
Yvan KOENIG (VALLAURIS, France) dimanche 7 septembre 2014 10:06:48