excluded dates in events in Calendar

In Calendar, I have an event that repeats once a week, every Monday, at 1PM.

There are some dates where I don’t want it repeated, so tried to use the excluded dates property of events.

set excludedDates to {}
set end of excludedDates to date "Monday, April 5, 2021 at 12:00:00 AM"
set end of excludedDates to date "Monday, May 3, 2021 at 12:00:00 AM"
set end of excludedDates to date "Monday, June 14, 2021 at 12:00:00 AM"

tell application "Calendar"
	set excluded dates of event 1 of calendar 1 to excludedDates
	excluded dates of event 1 of calendar 1
end tell

The above script does not end up modifying the excluded dates property. Anybody have experience modifying that property?

I tried adjusting the time for the excludes dates to 1:00:00 PM as well, but that didn’t work either.


You can’t set excluded dates of recurrent event (at least, using plain AppleScript). Because it is not real set of events but one rule fully controlled by the app only. If you cut or delete manually some day of recurrent event, popups confirmation dialog. Every changing of property which with manually way popups dialogs, isn’t scriptable with plain AppleScript.

I think, controlling (applying) the rules is possible by NSCalendar of AsObjC. But at moment I don’t know programming NSCalendar. Maybe, some expert of NSCalendar will help.

One plain AppleScript solution is: create real event for every day instead of recurrent event, using the first day’s event as template:

set firstDate to date "Monday, January 4, 2021 at 12:00:00 AM" -- 1st day of pseudo-recurrent event
set excludedDates to {}
set end of excludedDates to "Monday, April 5, 2021" -- your local dates here 
set end of excludedDates to "Monday, May 3, 2021"
set end of excludedDates to "Monday, June 14, 2021"

tell application "Calendar" to tell calendar 1
	repeat with i from 0 to 365 by 7 -- 1 year events creating by 1 week
		set startDate to firstDay + i * days
		set dateString to date string of startDate
		if not (excludedDates contains dateString) then
			make new event with properties {start date:startDate, end date:(startDate + 5 * minutes), allday event:false, summary:"WEEK RECURRED EVENT"}
		end if
	end repeat
end tell

I see. So the excluded dates property only applies to events that last multiple days, right? So in other words, if I have an event that is 30 days long, I can choose to exclude specific days within that 30 day period. That explains it. Thank you.

They apply only to events which “recur” (ie. repeat). Calendar’s AppleScript implementation only gives access to the root event of a recurring event, but this event’s excluded dates property should give the dates of recurrences which have been manually deleted in the application. Unfortunately, it doesn’t seem possible to set them using Calendar’s AppleScript implementation.

However, the task is doable using Shane’s CalendarLib library (download link currently on this page), which can handle repeats of recurring events as if they were events in their own right. It comes with instructions for installation in a Libraries folder. It edits the Calendar database without involving the Calendar application, so to avoid clashes, I tested this script without Calendar being open:

use AppleScript version "2.5" -- Mac OS 10.11 (El Capitan) or later.
use script "CalendarLib EC" version "1.1.4"
use scripting additions

on excludeDates(calendarName, eventSummary, datesToExclude)
	set theStore to fetch store
	-- The calendar type and date range might need to be adjusted in a finished script:
	set theCalendar to fetch calendar calendarName cal type cal local event store theStore
	set theEvents to fetch events starting date (current date) ending date ((current date) + 365 * days) searching cals {theCalendar} event store theStore
	set filteredEvents to filter events event list theEvents event summary eventSummary
	repeat with thisEvent in filteredEvents
		set recurrenceDate to (event info for event thisEvent)'s event_original_date
		if (recurrenceDate is in datesToExclude) then
			remove event event thisEvent event store theStore without future events
		end if
	end repeat
end excludeDates

-- Edit these as required:
set calendarName to "@Test"
set eventSummary to "Excluded dates test"
set excludedDates to {}
set end of excludedDates to date "Monday, April 5, 2021 at 1:00:00 PM"
set end of excludedDates to date "Monday, May 3, 2021 at 1:00:00 PM"
set end of excludedDates to date "Monday, June 14, 2021 at 1:00:00 PM"

excludeDates(calendarName, eventSummary, excludedDates)

Thank you, I’ll investigate Shane’s script when I get a chance.