Find files by month ignoring the year, with AppleScript

I find that I take a lot of pictures of seasonal stuff, and  I wondered how to find images taken at the same time of year but in different years.  As it turns out, there’s no obvious way to do that.  Computers keep time by counting the number of ticks or seconds since an arbitrary start date, and calculate a particular date and time  from the number of ticks.  So most date functions treat time in its relation to the arbitrary start date.  Mac OSX gives the current date as “Saturday, June 8, 2013 9:33:35 AM”, but when you search by date from iPhoto or Aperture,

Date search in Aperture
Date search in Aperture

you can only search for time periods relative to a given time.  It might be handy to add a “contains” to the list, eg, “Date contains May”, but alas.

Nevertheless,  AppleScript can easily parse a file’s creation date to let us search for files by “month of creation date”,  which might return “June” or a day of the week with “weekday of creation date”, which might return “Saturday”.

Here’s a simple script which has you choose a folder, then uses the Finder’s label index property to label all files with “May” in their creation date.  The script will find all files in the folder made in the chosen month, label them with one of 8 indices (0 thru 7; 0 is no label).  It sorts the finder window by label, so all your labels are grouped; then it selects the labeled files.  From the Finder, you can run QuickLook by touching your  spacebar.  You can then browse all the files from May no matter what year.  We’re hard-coding the label index (5) and month (May) for now.

set the_folder to choose folder with prompt "Select a folder:"
set the_label_index to 5
--label index:
-- 0=none
-- 1=orange
-- 2=red
-- 3=yellow
-- 4=blue
-- 5=purple
-- 6=green
-- 7-grey

tell application "Finder"
    activate
    set the_files to every file of the_folder
    repeat with current_file in the_files
        set the_creation_date to creation date of current_file
        set the_month to month of the_creation_date
        --we're hard coding the month now but will assign a variable in the next version
        if the_month is May then
            set the label index of current_file to the_label_index
        end if
    end repeat
    sort the_folder by label index
    select (every document file of the_folder whose label index is the_label_index)
end tell

It would make it easier for the user to select the month from a list, especially since month names vary by OSX language preferences.  Also, who knows what label index goes with what color?  We can use AppleScript’s choose from list method  to make those selections easier:

set the_month to choose from list {January, February, March, April, May, June, July, August, September, October, November, December} with prompt "Choose a month"
if the_month is false then error -128 --handles cancel button
--the chosen month is an item of a list, so we need to get it from the list
set chosen_month to item 1 of the_month

set the_label to choose from list {0, 1, 2, 3, 4, 5, 6, 7} with prompt "Choose a label; 0 is none, 1 orange, 2 red, 3 yellow, 4 blue, 5 purple, 6 nauseous green, 7 grey"
if the_label is false then error -128 --handles cancel button
set the_label_index to item 1 of the_label

Also, you may want to have the script navigate folders recursively.  For that, we turn the script into a subroutine.  The script calls the subroutine, then call it again for each sub-folder.   Here’s a script that does that:

--Label files by month
--recursively gets month of creation date and sets label for chosen month
--jjmcclintock 20130606

set the_folder to (choose folder)
set the_month to choose from list {January, February, March, April, May, June, July, August, September, October, November, December} with prompt "Choose a month"
--need to handle error if user cancels
if the_month is false then error -128
--the chosen month is an item of a list, so we need to get it from the list
set chosen_month to item 1 of the_month
--it would be nice to call the labels by color name and let the script convert your choice to index numbers, but
--putting that in the prompt is as far as I'm likely to go with it.
set the_label to choose from list {0, 1, 2, 3, 4, 5, 6, 7} with prompt "Choose a label; 0 is none, 1 orange, 2 red, 3 yellow, 4 blue, 5 purple, 6 nauseous green, 7 grey"
if the_label is false then error -128
set the_label_index to item 1 of the_label

--call the subroutine, passing the chosen parameters
label_for_month(the_folder, chosen_month, the_label_index)

--the subroutine:
on label_for_month(the_folder, chosen_month, the_label_index)
    tell application "Finder"
        --Check each of the  files in this folder
        set the_files to every file of the_folder
        repeat with current_file in the_files
            set the_creation_date to creation date of current_file
            set the_month to month of the_creation_date
            if the_month is chosen_month then
                set the label index of current_file to the_label_index
            end if
        end repeat
        sort the_files by label index
        --now each sub-folder
        set sub_folders_list to folders of the_folder
        repeat with the_sub_folder_ref in sub_folders_list
            my label_for_month(the_sub_folder_ref, chosen_month, the_label_index)
        end repeat
        sort the_files by label index
    end tell
end label_for_month

The script sorts the files by label, so you should see big blocks of similarly colored file labels. The script can’t select files across folders, but you can select them manually and run QuickLook (spacebar).  While the script is non-destructive, you may want to use it with care with folders that have many sub-folders; it can take a long time to run.  If you use labels for other purposes, this will! make a mess.

It should be fairly easy to modify this script to move or copy selected files if you want them for, for example, a calendar project. The choose from list method also supports multiple selections (“multiple selections allowed“) but you would have to futz with the the_label_index variable to make it work right.  It seems like overkill. But  for getting Saturday ball game snapshots from years past, or April invoices, or Christmas movies, this should do the trick.

Leave a Reply