Jacjac

Q: Applescript to take a file name element to change Date Created

This so beyond me but I have been led to believe is can be done. Can anyone help me please?

I have thousands of archive files. ALL of these files' names start with the date in dd-mm-yy format. eg. 31-01-11 File Name.pdf or 25-12-09 Filename-02.pdf

I would like to be able to drag a folder onto an application and for that app to search through the folder and all sub-folders, for these files and change the files' Date Created to the date at the start of the filename.

This feels so easy to type but I fear much more complicated to do however I do thank you very much in anticipation for your help.

Best wishes
---
John

MAcBok Pro, Mac OS X (10.6.6)

Posted on Jan 31, 2011 4:11 PM

Close

Q: Applescript to take a file name element to change Date Created

  • All replies
  • Helpful answers

  • by Camelot,

    Camelot Camelot Feb 1, 2011 8:34 AM in response to Jacjac
    Level 8 (47,290 points)
    Mac OS X
    Feb 1, 2011 8:34 AM in response to Jacjac
    This is actually harder than it sounds because there's nothing built-into AppleScript that will let you change the creation date of a file. You can get the date, but not set it.

    All is not lost, though, since you can reset creation dates via the shell command touch (provided the date you specify is earlier than the current date - you can't create dates in the future).

    Note, also, that file dates include an hour and minute specifier. Without them all your files will be recorded as created at midnight on the given date, which may or may not be a problem.

    Finally, for now, there are many ways this could go wrong, so a full-fleshed script would probably need some error checking (e.g. validate the file name to ensure it starts with something that resembles a date). I've omitted that here, but it's worth considering.

    This script is untested, so run it on a copy of your folders, first, just in case

    on open of theFiles
      -- This is executed when files are dropped on the script
      repeat with i in theFiles
        if folder of (info for i) then
          processAFolder(i)
        else
          processAFile(i)
        end if
      end repeat
    end open

    on processAFile(theFile)
      set theName to name of (info for theFile)
      try
        set dd to characters 1 through 2 of theName as text as integer
        if dd < 10 then set dd to "0" & dd
        set mm to characters 4 through 5 of theName as text as integer
        if mm < 10 then set mm to "0" & mm
        set yy to characters 7 through 8 of theName as text as integer
        if yy < 10 then set yy to "0" & yy
        do shell script "touch -t " & yy & mm & dd & "0000 " & quoted form of POSIX path of theFile
      end try
    end processAFile

    on processAFolder(theFolder)
      tell application "Finder"
        set theContents to items of folder theFolder as alias list
      end tell
      repeat with i in theContents
        if folder of (info for i) then
          processAFolder(i)
        else
          processAFile(i)
        end if
      end repeat
    end processAFolder


    It's pretty long, but if you need any explanation of the logic just let me know.
  • by The Preacher,

    The Preacher The Preacher Feb 1, 2011 8:40 AM in response to Jacjac
    Level 2 (185 points)
    Feb 1, 2011 8:40 AM in response to Jacjac
    Oops, Camelot beat me to it. Yup, Camelot's approach is the angle I was thinking of.

    Message was edited by: The Preacher
  • by Jacjac,

    Jacjac Jacjac Feb 1, 2011 10:43 AM in response to Camelot
    Level 1 (0 points)
    Feb 1, 2011 10:43 AM in response to Camelot
    Camelot, thank you so much for taking the time to do this. I will test this tomorrow and get back to you with more questions or issues then.

    I am truly grateful.

    Kind regards

    John
  • by Jacjac,

    Jacjac Jacjac Feb 1, 2011 4:06 PM in response to Jacjac
    Level 1 (0 points)
    Feb 1, 2011 4:06 PM in response to Jacjac
    OK Camelot, I have tested this and it does work but not on all files. It will not run on .pages files (it throws up "cannot make every item of <<class cfol>>...) Means nothing to me but I am sure you'll know.

    It would be nice to check/validate for the correct date at the start of the file name also.

    If you would like to go off forum and I can discuss some remuneration as I would be more than happy to pay you for your time. If you are good with AS then I have a couple of other small things, around file renaming and managing my archives etc, that you may be able to help me with.

    Again thanks
    ---
    John
  • by Camelot,

    Camelot Camelot Feb 1, 2011 4:33 PM in response to Jacjac
    Level 8 (47,290 points)
    Mac OS X
    Feb 1, 2011 4:33 PM in response to Jacjac
    It will not run on .pages files


    ahh, yes - I did say it was untested I'm guessing that's caused by certain 'files' are actually being bundles of files that the script is seeing as a directory - shouldn't be hard to fix.

    It would be nice to check/validate for the correct date at the start of the file name also.


    As written the script includes checks to make sure that there are at least numbers in the 1-2, 4-5 and 7-8 character positions, but there's no validation that they're valid dates (e.g. 38347372 would pass the check and get interpreted as 38-47-1972 which clearly makes no sense). Again, a little extra error checking should help.

    If you want to discuss this, or other scripts, in more detail, my email is camelot at me.com
  • by The Preacher,

    The Preacher The Preacher Feb 2, 2011 4:17 AM in response to Camelot
    Level 2 (185 points)
    Feb 2, 2011 4:17 AM in response to Camelot
    Hey Camelot,

    Are you finding that touch is working reliably? I find I can use it once to change a creation date, but on subsequent runs it'll only change the modification date?

    I came-up with this approach, but it fails on the second run (due to this odd touch behaviour). This version deals with bundles. It uses one of the handlers from your script.

    on open of theFiles
    set oldDelims to AppleScript's text item delimiters
    display dialog (theFiles as string)
    set filesAndFolders to do shell script ("find " & POSIX path of (theFiles))
    set numberOfPaths to count of text items in filesAndFolders

    repeat with counter from 1 to numberOfPaths
    set AppleScript's text item delimiters to return
    try
    set theFile to POSIX file (text item counter of filesAndFolders) as alias
    end try
    --Is it a file or folder? Bundles are correctly read as files
    if (my isItAFile(theFile)) then
    --This is a file, so let's try to change its date
    my processAFile(theFile)
    end if
    --end tell
    end repeat

    set AppleScript's text item delimiters to oldDelims
    return
    end open



    on processAFile(theFile)
    set AppleScript's text item delimiters to ""
    set theName to name of (info for theFile)

    try
    set dd to characters 1 through 2 of theName as text as integer
    if dd < 10 then set dd to "0" & dd
    set mm to characters 4 through 5 of theName as text as integer
    if mm < 10 then set mm to "0" & mm
    set yy to characters 7 through 8 of theName as text as integer
    if yy < 10 then set yy to "0" & yy
    do shell script "touch -t " & yy & mm & dd & "0000 " & quoted form of POSIX path of theFile
    end try
    end processAFile


    on isItAFile(theFile)
    --Are we dealing with a file or folder. Bundles are considered to be files
    tell application "Finder"
    try
    file type of file theFile
    return true
    on error
    return false
    end try
    --return name of theFile
    end tell
    end isItAFile
  • by Camelot,

    Camelot Camelot Feb 2, 2011 8:27 PM in response to The Preacher
    Level 8 (47,290 points)
    Mac OS X
    Feb 2, 2011 8:27 PM in response to The Preacher
    Are you finding that touch is working reliably? I find I can use it once to change a creation date, but on subsequent runs it'll only change the modification date?


    Touch works, provided you're setting the date backwards. If the date you're setting is later than the current creation date, or is a date in the future, then the creation date won't change.

    I'd expect this to be some kind of safeguard against having files that have creation dates later than the modification date.
  • by The Preacher,

    The Preacher The Preacher Feb 3, 2011 2:39 AM in response to Camelot
    Level 2 (185 points)
    Feb 3, 2011 2:39 AM in response to Camelot
    That explains it. Cheers.
  • by Hiroto,

    Hiroto Hiroto Feb 4, 2011 12:35 PM in response to Jacjac
    Level 5 (7,306 points)
    Feb 4, 2011 12:35 PM in response to Jacjac
    Hello

    Here's something you might try if the problem is still open.
    It uses SetFile(1) command in Developer Tools, which you need to have intalled.

    cf.
    http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/m an1/SetFile.1.html

    It can set creation date to any date between 1970-01-01 to 2038-01-18 inclusive.
    Simple check for date in file name is implemented so that error log is written to a log file on desktop when given date is considered invalid or SetFile raises error.

    One thing to note.
    It will process both files and directories under given directory tree in order to process package file. But it is not smart enough to leave the package contents alone, which means if a package contains a file or directory with name matching the pattern, it's creation date will be also changed.

    Minimally tested under OSX 10.2.8 at hand.
    But NO WARRANTIES of any kind. Please use it on test folder first.
    Good luck,
    H


    --SCRIPT
    on open aa
    main(aa)
    end open

    on run
    open ((choose folder) as list)
    end run

    on main(aa)
    (*
    list aa : alias list of source directories
    *)
    set logf to (path to desktop)'s POSIX path & "creationdate_error_log" & (current date)'s time & ".txt"
    repeat with a in aa
    set a to a as alias
    if (a as Unicode text) ends with ":" then -- directory
    set p to a's POSIX path's text 1 thru -2 -- posix path without trailing /

    set sh to "path=" & p's quoted form & ";
    logf=" & logf's quoted form & ";
    find "$path" -name '[0-9][0-9]-[0-9][0-9]-[0-9][0-9]*' -print0 | while read -d $'\0' f;
    do
    fn=${f##*/};
    dd=${fn:0:2}; ((d=10#$dd));
    mm=${fn:3:2}; ((m=10#$mm));
    yy=${fn:6:2}; ((y=10#$yy));
    if [[ ($d -ge 1 && $d -le 31) && ($m -ge 1 && $m -le 12) && ($y -ge 70 || $y -le 38) ]]; then
    if [[ $y -ge 70 ]]; then
    cc=19;
    else
    cc=20;
    fi
    res=$(/Developer/Tools/SetFile -d "$mm/$dd/$cc$yy 00:00" "$f" 2>&1);
    if [[ -n $res ]]; then
    echo "# $res ; failed for : $f" >> $logf;
    fi
    else
    echo "# invalid date in name : $f" >> $logf;
    fi
    done"
    do shell script sh
    end if
    end repeat
    end main
    --END OF SCRIPT
  • by Nameless68,

    Nameless68 Nameless68 Jul 12, 2011 12:14 PM in response to Camelot
    Level 1 (14 points)
    Jul 12, 2011 12:14 PM in response to Camelot

    Sorry to interrupt, but this is something I have been trying to do with my video files collection, because I need to convert them but the original date is not kept. I change the name of the file to simple like 20110108132326.mov with contains the yyyymmddhhmmss.mov.

     

    I tried the first script that was posted. Copied into the applescript editor, compiled it and saved as an application. I tested by renaming my file like the original poster and it does not change the date. I also saved as script is ran from the menu with the files selected and it still did not work. I never tried applescript before so I may be missing something simple. It seems to be running, but nothing changes. Thanks for any help.

  • by Fockz,

    Fockz Fockz Sep 22, 2016 7:12 PM in response to Camelot
    Level 1 (4 points)
    Sep 22, 2016 7:12 PM in response to Camelot

    Thank you so much Camelot for this answer. Also thank you Jacjac for posting the original question! A 5-year old post that apparently is still very helpful for my issue.

     

    A little background: I have an Android camera that stores files as "yyyymmdd_hhmmss.jpg", I store photos in Google Photos (usually using its auto-backup feature, or its Android app, except in certain cases), and use a Mac.

     

    In some cases Google Photos takes the creation/modification date (unsure) as opposed to the EXIF data for some reason (not always consistent in my observation). However, being Android, every time you move or copy a file within it, the creation/modification date is also updated, and it so happens that I was not able to maintain the original times. The adjusted times causes my photos to appear out of sequence. Thus I needed to modify the times myself, based on either EXIF or filename, and here we have a solution based on the filename.

     

    So here's the updated version of the above script, taking into account the seconds indicated in the filename. As you can see, I only modified it to fit my filename syntax.

     

    on open of theFiles

    -- This is executed when files are dropped on the script

      repeat with i in theFiles

      if folder of (info for i) then

      processAFolder(i)

      else

      processAFile(i)

      end if

      end repeat

    end open

     

    on processAFile(theFile)

      set theName to name of (info for theFile)

    -- Assumes file syntax begins with YYYYMMDD_hhmmss

      try

      set yy to characters 3 through 4 of theName as text as integer

      if yy < 10 then set yy to "0" & yy

      set mm to characters 5 through 6 of theName as text as integer

      if mm < 10 then set mm to "0" & mm

      set dd to characters 7 through 8 of theName as text as integer

      if dd < 10 then set dd to "0" & dd

      set hr to characters 10 through 11 of theName as text as integer

      if hr < 10 then set hr to "0" & hr

      set min to characters 12 through 13 of theName as text as integer

      if min < 10 then set min to "0" & min

      set sec to characters 14 through 15 of theName as text as integer

      if sec < 10 then set sec to "0" & sec

      do shell script "touch -t " & yy & mm & dd & hr & min & "." & sec & " " & quoted form of POSIX path of theFile

      end try

    end processAFile

     

    on processAFolder(theFolder)

      tell application "Finder"

      set theContents to items of folder theFolder as alias list

      end tell

      repeat with i in theContents

      if folder of (info for i) then

      processAFolder(i)

      else

      processAFile(i)

      end if

      end repeat

    end processAFolder

     

    Peace!