iCal’s event scheduling options are relatively powerful—you can set up events that occur on a variety of daily, weekly, monthly, or even yearly schedules. However, there’s one seemingly-simple thing that iCal doesn’t let you do: create an event that occurs on the last day of every month, or some mix of days and the last day of the month. Consider your paycheck. Many companies pay on the 15th and the last day of the month. If you use iCal to track your bill-due and income-received dates, this is a bit of a problem. But if you’re willing to get just a bit geeky (it is Friday, after all!), there’s a solution at hand…
The first thing to do is to create your new event, and create its schedule as close to what you desire as possible. To create the above “15th and last day” event, for instance, you’d set up a custom repeat for those two days each month. Create the event, then select Custom from the Repeat pop-up menu in the event’s Info window. Within the Custom dialog, set the Frequency pop-up to monthly, and click on the 1st and the 15th, like this:
Click OK, and you should see the repeating event appear on your calendar. Here’s a dummy event I put on a new calendar, just to make it easier to see without all my usual iCal clutter:
Although that may be a bit small to see all the details, you can see that the orange events are occuring on the 1st and 15th of December. Once you have the event set up, it’s time to go modify the event to do exactly what you’d like it to do. Before you do anything else, though, quit iCal.
Now things get a bit tedious—you need to figure out exactly where in the iCal data files your event is stored. iCal keeps your calendars in your user’s Library: Application Support: iCal: Sources folder. Within this folder, you’ll see a series of complexly-named folders, one for each and every calendar you have in iCal:
Within each of those, you’ll find a number of files, including a corestorage.ics file. This is the actual calendar file we need to modify. But how do you figure out which one you need to open? There are a few things to try to make the process easier. First, sort the Sources folder by Date Modified in the Finder, and open the top-most calendar folder. Assuming you didn’t do anything else with iCal events, and that you quit iCal relatively soon after adding the new event, this should be the folder you’re looking for. If, after opening it as described below, you find that it wasn’t the right folder, you can do one of two things. If you don’t have a lot of calendars, trial and error may be the quickest solution.
If you do have a lot of folders, switch to the Terminal and run these two commands:
$ cd ~/Library/Application Support/iCal/Sources $ find . -name corestorag* -ls | sort -M -k8,10
This should spit out a number of matches which look something like this:
... 7289 Nov 8 04:56 ./13A3E82C-8F1C-43C9-A66D-6A42C7E81695.calendar/corestorage.ics ... 8813 Nov 8 04:56 ./DC7E1EC1-CEF3-4DCC-B02F-060C95C6C641.calendar/corestorage.ics ... 1037 Nov 8 04:56 ./85D2678B-4163-4BB6-8454-A85C957E5B34.calendar/corestorage.ics ... ... 111 Nov 9 09:32 ./205220CB-0598-4C04-B9E7-54D4D3AC4126.calendar/corestorage.ics
I’ve removed a good chunk of the left-side of each line of output, just so it fits here. The important bits are on the right side, as they contain the modification time of the file, as well as the file’s containing folder. The command you ran sorts the output by date, such that the newest file is at the bottom of the list. Note the containing folder’s name, and then navigate to that folder (in either the Terminal or the Finder). Open the corestorage.ics file within that folder, using your favorite pure-text editor, be that
or BBEdit or TextEdit. Use your editor’s search function to search for the name of the event you created, and you should see something like this:
BEGIN:VCALENDAR CALSCALE:GREGORIAN PRODID:-//Apple Computer, Inc//iCal 2.0//EN VERSION:2.0 BEGIN:VEVENT DTSTART;VALUE=DATE:20051101 DTEND;VALUE=DATE:20051102 SUMMARY:Pay Day! UID:EC10040F-7CCA-4DE0-8FB7-3EB9C552FD5A RRULE:FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=1,15 DTSTAMP:20051109T172736Z SEQUENCE:5 END:VEVENT END:VCALENDAR
If you’ve got more than one event on this calendar, the above section will be found amongst other similar sections, one per event on that calendar. If you don’t find your event’s name, that means you’ve gotten the wrong corestorage.ics file. Close that one, and try one of the others.
Once you’ve found the relevant section of the file, you’re interested in only one line. Change the
by modifying the
Once you’ve made this simple change, save the file and quit the editor. Before we test it, though, you might wonder exactly what you just did. Basically, you’ve now told iCal to repeat the event on the “first to the last day” of the month, as well as the 15th of the month.
While you may think you’ve tricked iCal into doing something it shouldn’t do, Macosxhints reader Tom Robinson points out that this is actually part of the
Internet Calendaring and Scheduling Core Object Specification
three times quickly!), which Apple uses for its .ics files. In that spec, it has this to say about the
The BYMONTHDAY rule part specifies a COMMA character (ASCII decimal 44) separated list of days of the month. Valid values are 1 to 31 or-31 to -1. For example, -10 represents the tenth to the last day of the month.
So you’re not locked into the last day of the month; you could use
for the fifth day prior to month end, etc.
But enough of the technical jargon—let’s see if it worked! Launch iCal, and you should see that your event is now set to occur on the 15th and the last day of each month. Again, here’s December, and you can now see three events listed—the 30th of November, December 15th, and December 31st:
The only (very minor) irritation with this trick is that the “Repeat” value in the Info window now reads every month, each and 15th . But that doesn’t seem to affect anything, and alarms all work as expected. Hopefully, Apple will someday allow us to do the ‘before the end’ scheduling directly within iCal. But until then, this will have to suffice.