Address Book already coordinates with iCal to create events based on the date in any contact’s birthday field. If all you only need alarms, then you just need a way to add alarms to these events.
The catch is that iCal’s user interface presents the calendar as if it were read-only. But to AppleScript, the calendar is not actually read-only. You can use AppleScript to add alarms to the events in the “Birthdays” calendar:
on run
(* Warning:
This program will delete all the "display alarms" from the events in the
synthetic "Birthdays" calendar. Usually, there are no alarms on these
events because iCal treats this calendar as if it were read-only.
The calendar is not, however, actually read-only when accessed through
AppleScript. This program deletes all existing "display alarms" for all
birthdays and sets a new one for 13.5 days before the the event
(i.e. noon 14 days before, since the event occurs at midnight).
*)
tell application "iCal"
set bcName to "Birthdays"
set bc to a reference to calendar bcName
if not (exists bc) then
display alert "No “" & bcName & "” calendar!"
return
end if
repeat with e in events of contents of bc
-- make the following conditional if you only want alarms for some birthdays
tell e
delete display alarms
make new display alarm with properties {trigger interval:-13.5 * 24 * 60}
end tell
end repeat
end tell
end run
Every time you run this program it will, effectively, make sure every birthday has an alarm on it.† It looks like Address Book makes only minimal changes when it updates a birthday event for a changed name or birthday date; the alarms persist across updates from Address Book, but this may not be reliable since Address Books “owns” these events and could completely delete and recreate them any time it felt the need to do so.
I do not know of an official way to be notified of Address Book changes, but as the other answerer suggests, you might be able to hook up a Folder Action to the folder that holds the events for the “Birthdays” calendar. You can open that folder with this program:
tell application "iCal" to set bcuid to uid of calendar "Birthdays"
path to library folder from user domain
tell application "Finder" to open folder "Events" of folder (bcuid & ".calendar") of folder "Calendars" of result
Since this is an internal detail, it may not be reliable across different OS versions. All of the above was developed and tested on Mac OS X 10.6.8.
Alternatively, since the above program ensures every birthday has an alarm, you could just arrange to run it once a day or once at login (you can use an iCal event with a “Run Script” alarm, or save the program as an application and set it as a login item).
Creating your own events (in your own calendar) is certainly possible, but keeping them synchronized with the birthday data can be tricky (lookup by “name and date” is usually not sufficient because the user could change either of those, and your “make alarms” program may not be able to determine the original values by the time it knows a particular contact has been updated with a new name or birthday date). Address Book solves this problem by encoding the contact’s internal, unique identifier into the URL it saves into each birthday event’s url
property; since the calendar is “read-only” it does not have to worry about a user changing or deleting its special URLs, so it can rely on them being accurate.
† We delete all existing alarms on the assumption that all the alarms are “ours” since Address Book does not add alarms on its own, and iCal does not let users add alarms.
Unfortunately, there is no extra property where we could add any kind of unique identifier to the alarm itself (although if the exact time of the alarm is not important, it might be possible to encode some information in the numeric value of the alarm’s minute offset).
It seems easier to just delete the alarms and create exactly the one we want instead of checking any existing alarms to see if they match our current desired alarm setting.