delete calendar events

I’m trying to change events in my Calendar using applescript.
Creating new events is no problem. However, any attempt to delete certain events in my Calendar seems to be ignored.
For instance the following code:

set TheDate to current date
tell application “Calendar”
tell calendar “BB2”
delete (events whose start date is TheDate and summary is “Birthday”)
end tell
end tell

How should I deal with this?

You could try this…

its deleteEventsByDate(date "Monday, 24 October 2022 at 18:00:00", "Birthday")

on deleteEventsByDate(startDate, theSummary)
    tell application "Calendar"
        tell calendar "Events"
            repeat with i from 1 to (count events)
                if startDate is (start date of event i) then
                    if theSummary is (summary of event i) then
                        delete event i
                    end if
                end if
            end repeat
        end tell
    end tell
end deleteEventsByDate

Or you could do it like this

its deleteEventsByDate(date "Monday, 24 October 2022 at 18:00:00", "New Event")

on deleteEventsByDate(startDate, theSummary)
    tell application "Calendar"
        tell calendar "Events"
            repeat with i from 1 to count events
                if ((start date of event i is in startDate) and (summary of event i is in theSummary)) then
                    delete event i
                end if
            end repeat
        end tell
    end tell
end deleteEventsByDate
(**
* [deleteEventsByDateAndSummary(date, string , string)]
*)

its deleteEventsByDateAndSummary(date "Monday, 24 October 2022 at 15:00:00", "New Event", "Events")
on deleteEventsByDateAndSummary(startDate, theSummary, calendarName)
	tell application "Calendar"
		tell calendar calendarName
			delete (events whose (start date is startDate) and (summary is theSummary))
		end tell
	end tell
end deleteEventsByDateAndSummary

Dear Frederik,

thank you very much,but unfortunately, the script ignores the delete command.
In whatever setting you specified, it seems that ‘delete’ is not accepted.

I’m puzzled.

You have to make sure the input for the handler I made have the right information to be able to delete a event.

  1. What is your Calendar name
  2. The date is matching the date of your event
  3. The summary string is same for your event you made.

The handler input:
deleteEventsByDateAndSummary(startDate, theSummary, calendarName)

If startDate, theSummary or calendarName is incorrect nothing will happen.

To test the handler of post #3 you need to make a Calendar with name Events or change that to match your Calendar name.

  1. Make a Calendar with name Event
  2. Create a event 28 October with start time 15:00:00 and set the summary to Birthday
    Next
    Run this
its deleteEventsByDateAndSummary(date "Friday, 28 October 2022 at 15:00:00", "Birthday", "Events")

Have test the script on Monterey and it works for me.

I’m sorry, but the very first line of code is not accepted.
this first line of code is:
its deleteEventsByDateAndSummary(date “Monday, 24 October 2022 at 15:00:00”, “Voorkamer”, “BB2”)

the applescript debugger says:
invalid date and time Monday 24 October at 15:00:00
even if I delete the hour (as the event is an allday event) the same error is reported:
invalid date and time Monday 24 October.

So I made a workaround:

set TheDate to current date

and subsequently adjust TheDate to the date I want to use, reading the value of cells from FileMaker:

tell application “FileMaker Pro Advanced”
tell current layout
tell current record
set TheDay to cell “datumdag”
set TheMonth to cell “datummaand”
set TheYear to cell “datumjaar”
end tell
end tell

set the day of TheDate to TheDay
set the month of TheDate to TheMonth
set the year of TheDate to TheYear

This code is accepted, but the susbequent code does nothing, at least it does not delete the event on the selected date with summary is “Voorkamer” and in the calendar with the name “BB2”

its deleteEventsByDateAndSummary(TheDate, “Voorkamer”, “BB2”)
on deleteEventsByDateAndSummary(startDate, theSummary, calendarName)
tell application “Calendar”
tell calendar calendarName
delete (events whose (start date is startDate) and (summary is theSummary))
end tell
end tell
end deleteEventsByDateAndSummary

Oh, I forgot to mention: maybe it’s because my applescript is running on MacOs 10.13 (High Sierra)?

This works in Script Editor if you type: set theDate to date “24/10/22” – “Day/Month/Year”

Or

If you use US I guess it will be “Month/Day/Year”

Next When you compile the code it will change to the date format you use for your system.

Simple test on your system…

run this: set theDate to current date

In the log you will see the format that is acceptable for your system.

copy the log

edit your code to

set theDate to <copy_of_the_log>
change the day, month or year and time for your event

Here is a good reference how to use date in AppleScript
https://macscripter.net/viewtopic.php?id=24737

You could adapt this ASObjC script to make a better date format to feed your needs.
Remember that start date is a class of date and not a string

use framework "Foundation"
use scripting additions

(**
* Reference:
*	https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/DataFormatting.html
*
* https://developer.apple.com/documentation/foundation/nsdateformatter
*
* https://nsdateformatter.com
*
* https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
*)

(**
* [YEAR]
* y, 2008, Year no padding
* yy, 08, Year two digits (padding with a zero if necessary)
* yyyy 2008, Year minimum of four digits (padding with zeros if necessary)
*)

(** 
* [QUARTER]
* Q, 4, The quarter of the year. Use QQ if you want zero padding.
* QQQ, Q4, Quarter including "Q"
* QQQQ, 4th quarter, Quarter spelled out
*)

(**
* [MONTH]
* M, 12, The numeric month of the year. A single M will use '1' for January.
* MM, 12, The numeric month of the year. A double M will use '01' for January.
* MMM, Dec, The shorthand name of the month
* MMMM, December, Full name of the month
* MMMMM, D, Narrow name of the month
*)

(** 
* [DAY]
* d, 14, The day of the month. A single d will use 1 for January 1st.
* dd, 14, The day of the month. A double d will use 01 for January 1st.
* F, 3rd Tuesday in December, The day of week in the month
* E, Tue, The abbreviation for the day of the week
* EEEE, Tuesday, The wide name of the day of the week
* EEEEE, T, The narrow day of week
* EEEEEE, Tu, The short day of week
*)

(**
* [HOUR]
* h, 4, The 12-hour hour.
* hh, 04, The 12-hour hour padding with a zero if there is only 1 digit
* H, 16, The 24-hour hour.
* HH, 16, The 24-hour hour padding with a zero if there is only 1 digit.
* a, PM, AM / PM for 12-hour time formats
*)

(**
* [MINUTE]
* m, 35, The minute, with no padding for zeroes.
* mm, 35, The minute with zero padding.
*)

(**
* [SECOND]
* s, 8, The seconds, with no padding for zeroes.
* ss, 08, The seconds with zero padding.
* SSS, 123, The milliseconds.
*)

(**
* [TIME ZONE]
* zzz, CST, The 3 letter name of the time zone. Falls back to GMT-08:00 (hour offset)
* zzzz, Central Standard Time, The expanded time zone name, falls back to GMT-08:00
* ZZZZ, CST-06:00, Time zone with abbreviation and offset
* Z, -0600, RFC 822 GMT format. Can also match a literal Z for Zulu (UTC) time.
* ZZZZZ, -06:00, ISO 8601 time zone format
*)

-- Examples.
log (my dateFormatterWithFormat:"EEEE, MMM d, yyyy")
log (my dateFormatterWithFormat:"MM/dd/yyyy")
log (my dateFormatterWithFormat:"dd/MM/yyyy")
log (my dateFormatterWithFormat:"MM-dd-yyyy HH:mm")
log (my dateFormatterWithFormat:"dd-MM-yyyy HH:mm")
log (my dateFormatterWithFormat:"MMM d, h:mm a")
log (my dateFormatterWithFormat:"d MMM, h:mm a")
log (my dateFormatterWithFormat:"d MMM, HH:mm")
log (my dateFormatterWithFormat:"MMMM yyyy")
log (my dateFormatterWithFormat:"MMM d, yyyy")
log (my dateFormatterWithFormat:"E,d MMM yyyy HH:mm:ss Z")
log (my dateFormatterWithFormat:"yyyy-MM-dd'T'HH:mm:ssZ")
log (my dateFormatterWithFormat:"dd.MM.yy")
log (my dateFormatterWithFormat:"HH:mm:ss")
log (my dateFormatterWithFormat:"MMMM dd, yyyy HH:mm")
log (my dateFormatterWithFormat:"HH:mm, zzzz")
log (my dateFormatterWithFormat:"VV, VVVV, zz, ZZZZ")



if ((my dateFormatterWithFormat:"F") = "1") then
	log (my dateFormatterWithFormat:"F'st' EEEE 'in the month'")
end if
if ((my dateFormatterWithFormat:"F") = "2") then
	log (my dateFormatterWithFormat:"F'nd' EEEE 'in the month'")
end if
if ((my dateFormatterWithFormat:"F") = "3") then
	log (my dateFormatterWithFormat:"F'rd' EEEE 'in the month'")
end if
if ((my dateFormatterWithFormat:"F") = "4") or (my dateFormatterWithFormat:"F") = "5" then
	log (my dateFormatterWithFormat:"F'th' EEEE 'in the month'")
end if

(**
* [Class]: NSDateFormatter
*	A formatter that converts between dates and their textual representations.
*)

(**
* [dateFormatterWithFormat:(string)]
*)
on dateFormatterWithFormat:_dateFormat
	set formatter to current application's NSDateFormatter's alloc()'s init()
	formatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX")
	formatter's setDateFormat:(_dateFormat as string)
	set theString to (formatter's stringFromDate:(current date)) as text
end dateFormatterWithFormat:

log (my dateFormatterLocaleWithFormat:"'Idag' EEEE 'den' dd MMMM" locale:"sv")

(**
* [dateFormatterLocaleWithFormat:(string):locale:(string)]
*)
on dateFormatterLocaleWithFormat:_dateFormat locale:_localeString
	set formatter to current application's NSDateFormatter's alloc()'s init()
	formatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:_localeString)
	formatter's setDateFormat:(_dateFormat as string)
	set theString to (formatter's stringFromDate:(current date)) as text
end dateFormatterLocaleWithFormat:locale:

-- log (my worldClockWithFormat:"yyyy-mm-dd ':' HH:mm:ss")
log (my worldClockWithFormat:"HH:mm" timeZone:{"America/New_York", "Europe/Paris", "Australia/Sydney"})

(**
* [worldClockWithFormat:(string):timeZone:(list)]
*)
on worldClockWithFormat:_dateFormat timeZone:_timeZoneList
	set theList to {}
	repeat with i from 1 to (count _timeZoneList)
		set timeZoneName to item i of _timeZoneList
		set formatter to current application's NSDateFormatter's alloc()'s init()
		(formatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX"))
		(formatter's setDateFormat:(_dateFormat as string))
		(formatter's setTimeZone:(current application's NSTimeZone's timeZoneWithName:(timeZoneName as string)))
		set theString to (formatter's stringFromDate:(current date)) as text
		copy item i of _timeZoneList & space & theString to end of theList
	end repeat
	return theList
end worldClockWithFormat:timeZone:

(**
* [worldClockWithFormat:(string)]
*	Choose single item from a list of knownTimeZoneNames to return the time
*)
on worldClockWithFormat:_dateFormat
	set timeZoneName to choose from list (timeZoneNames() as list)
	set formatter to current application's NSDateFormatter's alloc()'s init()
	formatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX")
	formatter's setDateFormat:(_dateFormat as string)
	formatter's setTimeZone:(current application's NSTimeZone's timeZoneWithName:(timeZoneName as string))
	set theString to timeZoneName & space & (formatter's stringFromDate:(current date)) as text
end worldClockWithFormat:

(**
* [timeZoneNames]
*	Return a list of knownTimeZoneNames
*)
on timeZoneNames()
	set zoneNames to current application's NSTimeZone's knownTimeZoneNames()
	return zoneNames as list
end timeZoneNames

So you could do something like this…

use framework "Foundation"
use scripting additions

-- dateFormatterLocaleWithFormat:"dd-MM-yyyy HH:mm" locale:<the_systems_local_as_string>
set startDate to (its dateFormatterLocaleWithFormat:"28-10-2022 15:00" locale:"sv")

(**
* [deleteEventsByDateAndSummary(date, string , string)]
*)
its deleteEventsByDateAndSummary(date startDate, "Birthday", "Events")
on deleteEventsByDateAndSummary(startDate, theSummary, calendarName)
	tell application "Calendar"
		tell calendar calendarName
			delete (events whose (start date is startDate) and (summary is theSummary))
		end tell
	end tell
end deleteEventsByDateAndSummary

(**
* [dateFormatterLocaleWithFormat:(string) locale:(string)]
*)
on dateFormatterLocaleWithFormat:_dateFormat locale:_localeString
	set formatter to current application's NSDateFormatter's alloc()'s init()
	formatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:_localeString)
	formatter's setDateFormat:(_dateFormat as string)
	set theString to (formatter's stringFromDate:(current date)) as text
end dateFormatterLocaleWithFormat:locale:

But a more simple way is to do…

set dateString to "28/10/22 15:00"
set startDate to date dateString -- startDate is class of date

Hi.

Looking at Carolus’s original script, the potential issues are:

  1. Start dates in Calendar are exact to the second, so unless times are critical, a way has to be found to ignore them.
  2. Birthdays potentially occur every year. It’s not clear if a particular year’s intended here or every year. If an event’s been set as a repeating event, only the start date of its first instance is recognised in Calendar’s AppleScript implementation.
  3. After AppleScript deletes an event from Calendar, it may be necessary to quit and reopen Calendar before you see the effect.

Here’s an attempt to deal with the first of these issues:

on deleteEventsOfCalendar:calendarName bySummary:theSummary andStartDate:dateParts
	tell application "Calendar"
		set theCalendar to calendar calendarName
		set {summaries, startDates, ids} to {summary, start date, uid} of theCalendar's events
	end tell
	
	repeat with i from 1 to (count summaries)
		if ((item i of summaries = theSummary) and ({year, month, day, time} of item i of startDates contains dateParts)) then
			tell application "Calendar" to delete event id (item i of ids) of theCalendar
		end if
	end repeat
end deleteEventsOfCalendar:bySummary:andStartDate:

set calendarName to "BB2"
set theSummary to "Birthday"
-- The following list must contain values from an AppleScript date:
-- ie. the date's {year, month, day, time}. Values to be ignored can
-- be omitted, but the rest must be in the above order.
set dateParts to (current date)'s {month, day}

my deleteEventsOfCalendar:calendarName bySummary:theSummary andStartDate:dateParts

Thanks Nigel for your elaborate answer.
However, it seems that my mac consistently refuses any type of delete command.

To clarify, my agenda has on each day zero or just one event, which takes all day.
So, events are created as follows:

set EventU to “unavailable”
set TheDate to current date
tell calendar “One”
make new event at end with properties {summary:EventU, start date:TheDate, end date:TheDate, allday event:true}
end tell

this works.
But the opposite:
tell calendar “One”
delete (events whose summary equals EventU and start date is TheDate)
end tell

does not work
even the extended command:
delete (events whose summary equals EventU and start date is TheDate and end date is TheDate and allday event is true)
does not work.

Did you note my point 3 above about quitting and reopening Calendar after running your script? On my Mac, Calendar doesn’t update its display immediately when events are deleted by AppleScript. It has to be quit and then reopened before the event(s) can be seen to be gone.

The code you use have start time 00:00:00 and end time 00:00:00 the next day or beginning of next day. So when you use current time when you run the script it will not match.

To understand more I did some example.

First I need to know the properties
tell calendar “One”
its properties of event
end tell

Next, It show that start date have time of 00:00:00

So I made example that use your code and remove the event after 5 seconds. Look at the start time its not current time when you execute the code.

set EventU to "unavailable"
set TheDate to current date
set startDate to date "Wednesday, 26 October 2022 at 00:00:00"

tell application "Calendar"
	tell calendar "One"
		make new event at end with properties {summary:EventU, start date:TheDate, end date:TheDate, allday event:true}
	end tell
	
	delay 5
	
	tell calendar "One"
		delete (events whose (start date is startDate) and (summary is EventU))
	end tell
end tell

In Monterey it update this works without restart of Calendar. (Calendar “One” is selected)

set EventU to "unavailable"
set TheDate to current date
set startDate to date "Wednesday, 26 October 2022 at 00:00:00"

tell application "Calendar"
	tell calendar "One"
		make new event at end with properties {summary:EventU, start date:TheDate, end date:TheDate, allday event:true}
	end tell
	
	delay 5
	
	tell calendar "One"
		delete (events whose (start date is startDate) and (summary is EventU))
	end tell
end tell

I’ve altered the script, which now quits the Calendar and subsequently activates the Calendar again.
But to no avail.
All events that are created in my Calendar are allday events
And I do not understand.
I’ve even made new events only with a start date and summary, but the result is the same.
Any delete effort is ignored.
code:

set TheDate to current date

tell application “FileMaker Pro Advanced”
tell current layout
tell current record
set TheDay to cell “datumdag”
set TheMonth to cell “datummaand”
set TheYear to cell “datumjaar”
set NaamVoor to cell “naamVK”
set NaamAchter to cell “naamAK”
set NaamTuin to cell “naamTK”
end tell
end tell
end tell

-- this causes whatever the current date is, to adjust TheDate to the values selected in the cells of the record of FMP

set the day of TheDate to TheDay
set the month of TheDate to TheMonth
set the year of TheDate to TheYear

set EventU to “unavailable”

tell application “Calendar”
activate
tell calendar “BBVK”
make new event at end with properties {summary:EventU, start date:TheDate, allday event:true}
end tell
tell calendar “BBAK”
make new event at end with properties {summary:EventU, start date:TheDate, allday event:true}
end tell
tell calendar “BBTK”
make new event at end with properties {summary:EventU, start date:TheDate, allday event:true}
end tell
end tell

tell application “Calendar”
quit
end tell

tell application “Calendar”
activate
tell calendar “BBVK”
delete events whose (start date is TheDate) and (summary is EventU)
end tell
end tell
– this should delete the event which was just made.

tell application “FileMaker Pro Advanced”
activate
end tell

grrrrrrr

Hi Carolus.

  1. Try deleting the events before quitting and reopening Calendar. :slight_smile:

  2. It would be good if you could wrap your AppleScript code in MacScripter’s [applescript] and [/applescript] tags when posting here. They make the code appear in a box with a clickable link, as in Fredrik71’s posts and mine. There’s a button for them above the text field when you post. Thanks.

@Carolus

Please could you run this code, if that doesn’t work for you.
Check if the code with command delete to be the same date of day you run the script.

Today its 26… so if you run the code 27 October you need to change that line.
You only need to change the day nothing else

tell application "Calendar"
	set calendarNames to its name of every calendar
	if calendarNames does not contain "MyCal" then
		make new calendar with properties {name:"MyCal"}
	end if
	tell calendar "MyCal"
		make new event at end with properties {start date:(current date), summary:"MyEvent", allday event:true, end date:(current date)}
	end tell
	
	delay 3
	
	tell calendar "MyCal"
		delete (events whose (start date is (date "Wednesday, 26 October 2022 at 00:00:00")) and (summary is "MyEvent"))
	end tell
end tell