Applescript to create iCal event with Time Zone

Hello,

Does anyone know how I can tell an event to add time zone? I have searched on this forum and Google but found nothing so far. I did see a lot of questions but no reply :frowning: I really hope my new post will get some attention.

I need to be able to define timezone in my script when I am creating an iCal event. We can assume that I have already set the new event to “Event 1”.

Any help or suggestions would be greatly appreciated!

Thanks in advance!

Riz

Hi Riz,

As far as I can tell, iCal’s event object doesn’t support time zones through Applescript. I’ve done some iCal scripts for creating events, but there isn’t any time zone property in the event item. I know the program supports time zones, but don’t think that functionality has become scriptable. Yet.

Hi Kevin,

Thanks for informatin. Although its a bad news, it is still good for me since I now know not to run after something that doesnt exists.

Riz

Hi.

If you’re desperate for the functionality, it’s possible to edit the relevant calendar’s .ics file, though the script has to quit iCal while the edit takes place. It’s also vitally important not to make any mistakes in the file!

This has been tested with iCal 1.5.5 in Jaguar and iCal 2.0.5 in Tiger:

(* These handlers change the time zone of an iCal event without changing the clock time ” ie. the same clock time, not the same instant.
The main handler changeEventTimeZone() requires the UID of the event and the ID of the desired time zone ” eg. "Asia/Anadyr".
The script finds and manipulates the calendar file and has to quit iCal to do this, reactivating it afterwards.

IF ALTERING THIS SCRIPT, NOTE THAT A MISTAKE WHILE EDITING THE CALENDAR FILE COULD RESULT IN THE LOSS OF ALL THE EVENTS AND TODOS IN THE CALENDAR! BE VERY CAREFUL! USE A DUPLICATE CALENDAR UNTIL YOU'RE SURE YOU'VE GOT THE CODE RIGHT! *)

(* Main handler. *)
on changeEventTimeZone(theUID, timeZoneID)
	tell application "iCal" to quit
	tell application "System Events"
		repeat while (application process "ical" exists)
			delay 0.2
		end repeat
	end tell
	
	set rootPath to (path to application support from user domain as Unicode text) & "iCal:"
	if (listFolder(rootPath) contains "Sources") then
		-- iCal 2.0.5 calendar paths are: "(path to Application Support):iCal:Sources:(unknown UID*).calendar:corestorage.ics"
		-- [*] On my machine, (calendar UID returned by AppleScript) ≠ (calendar UID in file) ≠ (UID in folder name)!
		set rootPath to rootPath & "Sources:"
		set itemNames to listFolder(rootPath)
		set endBit to ":corestorage.ics" as Unicode text
	else
		-- iCal 1.5.5 calendar paths are: "(path to user Library):Calendars:(calendar name).ics"
		set rootPath to (path to "dlib" from user domain as Unicode text) & "Calendars:"
		set itemNames to listFolder(rootPath)
		set endBit to "" as Unicode text
	end if
	
	repeat with thisName in itemNames
		set calPath to rootPath & thisName & endBit
		set calText to (read file calPath as «class utf8»)
		if (calText contains theUID) then
			set newCaltext to processCalText(calText, theUID, timeZoneID)
			set fRef to (open for access file calPath with write permission)
			try
				set eof fRef to 0
				write newCaltext to fRef as «class utf8»
			end try
			close access fRef
			exit repeat
		end if
	end repeat
	
	tell application "iCal" to activate
end changeEventTimeZone

(* List a folder's visible items by the fastest available method. *)
on listFolder(folderPath)
	try -- 'list folder' deprecated, but faster than 'do shell script' while it still works.
		return (list folder file folderPath without invisibles)
	on error
		return paragraphs of (do shell script ("ls " & quoted form of POSIX path of folderPath))
	end try
end listFolder

(* Perform the required edit. *)
on processCalText(calText, theUID, timeZoneID)
	set UIDline to "UID:" & theUID
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "BEGIN:VEVENT" as Unicode text
	set eventBlocks to calText's text items
	repeat with i from 2 to (count eventBlocks)
		set thisBlock to item i of eventBlocks
		if (thisBlock contains UIDline) then
			set AppleScript's text item delimiters to "END:VEVENT" as Unicode text
			set eventText to text item 1 of thisBlock
			set AppleScript's text item delimiters to ";TZID=" as Unicode text
			set TIs to eventText's text items
			repeat with j from 2 to (count TIs)
				set thisTI to item j of TIs
				set item j of TIs to timeZoneID & text (offset of ":" in thisTI) thru -1 of thisTI
			end repeat
			set eventText to TIs as Unicode text
			set AppleScript's text item delimiters to "END:VEVENT" as Unicode text
			set item i of eventBlocks to eventText & "END:VEVENT" & text from text item 2 to -1 of thisBlock
			set AppleScript's text item delimiters to "BEGIN:VEVENT" as Unicode text
			set calText to eventBlocks as Unicode text
			exit repeat
		end if
	end repeat
	set astid to AppleScript's text item delimiters
	
	return calText
end processCalText


-- Demo code:
set theSummary to "Event 1"
set startDate to date "Sunday 18 October 2009 12:00:00"
set endDate to date "Sunday 18 October 2009 13:30:00"
set theTimeZone to "Asia/Anadyr"

tell application "iCal" to set theUID to uid of (make new event at end of events of calendar 4 with properties {summary:theSummary, start date:startDate, end date:endDate})

changeEventTimeZone(theUID, theTimeZone)

Hi Nigel,

That’s a very neat code. Thanks for code! I might have to end up using your code.

Thanks,

Riz