Applescript for calendar events - daylight savings time problems


#1

Hello,

I use an Applescript to parse calendar events from a numbers sheet into my macOS stock calendar app. Thanks for all the good advice and support in the Automators Episode 1 thread.

However, if I parse an event that is beyond the date when daylight savings time is in effect or vice versa, it changes the times of the respective event by ±1 hour.

Does anyone have the same problem or know how to fix this?

Thanks,
Felix


#2

I want to add some screenshots to illustrate the problem.

In the numbers table the dates are set to a date beyond the next change in DST next year.

When the script gets the values the local times are changed. This does not happen if the dates are prior to the next change in daylight savings time.

I do not know how to handle this and hope anyone can give me a hint how to fix this.

Thank you,
Felix


#3

Going from wintertime to summertime is hard, the  Watch people can tell you all about it. :wink:

If I understand correctly the time’s are not correctly transferred from Numbers with AppleScript, there is an hour difference. So to get the hour values correctly the script needs to know what the current Time Zone (including summer/wintertime) and the same for the date downloaded from Numbers. I haven’t been able to find if AppleScript supports this. Luckily the Unix part of the Mac does this. So with a do shell script command you can get this information.

I wrote the following sample script:

set DateTimeString to date "Montag, 27. Mai 2019 um 14:00:00"

set CurrentDTS to do shell script "date +%Z"
--Get the current Time Zone Abbreviation, CET or CEST

set {year:Jahr, month:Monat, day:Tag, hours:Stunden} to DateTimeString
--Get the individual parts of the date string
set Monat to Monat + 0
--Change the month from a word to a number

set IstDST to do shell script "date -jf \"%Y-%m-%d\" \"" & Jahr & "-" & Monat & "-" & Tag & "\" +\"%Z\""
--Get the Time Zone Abbreviation of the future date, CET or CEST

if (CurrentDTS is "CET") and (IstDST is "CEST") then
	set Stunden to Stunden - 1
	set hours of DateTimeString to Stunden
--change 14:00:00 to 13:00:00 in DateTimeString
end if

if (CurrentDTS is "CEST") and (IstDST is "CET") then
	set Stunden to Stunden + 1
	set hours of DateTimeString to Stunden
--change 14:00:00 to 15:00:00 in DateTimeString
end if

I couldn’t test this script in it’s final form, because the localisation of my Mac is Dutch, so it doesn’t accept the first line with the German text in the date string, I copied that from your example.

I hope this works on your Mac and that you can use it to solve your problem.


#4

Thank you for your support! By getting the time zone information via the shell script as you recommended I could finish the script.

Now it works as advertised with a numbers template and the stock calendar app.

:grinning:


#5

Here’s the script:

tell application "Numbers"
	activate
	tell front document
		tell front sheet
			tell front table
				set ZeileStart to address of first row of selection range
				-- setzt des Anfangsnummer der Zeile auf die erste Zeile
				set WievieleZeilen to the count of rows of selection range
				-- 	Wie oft muss die Schleife wiederholt werden?	
				
				repeat WievieleZeilen times
					set NameDesEvents to value of cell 1 of row ZeileStart
					set Anfangsdatum to value of cell 3 of row ZeileStart
					if value of cell 4 of row ZeileStart is not missing value then
						set Enddatum to value of cell 4 of row ZeileStart
					else
						set Enddatum to Anfangsdatum
					end if
					if value of cell 5 of row ZeileStart is not missing value then
						set OrtDesEvents to value of cell 5 of row ZeileStart
					else
						set OrtDesEvents to ""
					end if
					if value of cell 6 of row ZeileStart is not missing value then
						set NotizenDesEvents to value of cell 6 of row ZeileStart
					else
						set NotizenDesEvents to ""
					end if
					-- prüft, ob Notizen und Ort leergelassen wurden
					
					set WelcherKalender to value of cell 7 of row ZeileStart
					if value of cell 2 of row ZeileStart = true then
						-- prüft, ob ein ganztägiges Event vorliegt
						
						tell application "Calendar"
							tell calendar WelcherKalender
								set hours of Anfangsdatum to 12
								set hours of Enddatum to 12
								make new event with properties {summary:NameDesEvents, start date:Anfangsdatum, end date:Enddatum, description:NotizenDesEvents, location:OrtDesEvents, allday event:true}
							end tell
						end tell
					else
						
						-- Hier beginnt Anpassung der Zeit an die Zeitzone Sommer- / Winterzeit
						set AktuelleTZ to do shell script "date +%Z"
						--Get the current Time Zone Abbreviation, CET or CEST
						
						set {year:JahrAnfangsdatum, month:MonatAnfangsdatum, day:TagAnfangsdatum, hours:StundenAnfangsdatum} to Anfangsdatum
						--Get the individual parts of the date string
						set MonatAnfangsdatum to MonatAnfangsdatum + 0
						--Change the month from a word to a number
						
						set ZielTZ to do shell script "date -jf \"%Y-%m-%d\" \"" & JahrAnfangsdatum & "-" & MonatAnfangsdatum & "-" & TagAnfangsdatum & "\" +\"%Z\""
						--Get the Time Zone Abbreviation of the future date, CET or CEST
						
						if (AktuelleTZ is "CET") and (ZielTZ is "CEST") then
							
							set hours of Anfangsdatum to (hours of Anfangsdatum) - 1
							
						end if
						
						if (AktuelleTZ is "CEST") and (ZielTZ is "CET") then
							
							set hours of Anfangsdatum to (hours of Anfangsdatum) + 1
							
						end if
						
						set {year:JahrEnddatum, month:MonatEnddatum, day:TagEnddatum, hours:StundenEnddatum} to Enddatum
						--Get the individual parts of the date string
						set MonatEnddatum to MonatEnddatum + 0
						--Change the month from a word to a number
						
						set ZielTZ to do shell script "date -jf \"%Y-%m-%d\" \"" & JahrEnddatum & "-" & MonatEnddatum & "-" & TagEnddatum & "\" +\"%Z\""
						--Get the Time Zone Abbreviation of the future date, CET or CEST
						
						if (AktuelleTZ is "CET") and (ZielTZ is "CEST") then
							
							set hours of Enddatum to (hours of Enddatum) - 1
							
						end if
						
						if (AktuelleTZ is "CEST") and (ZielTZ is "CET") then
							
							set hours of Enddatum to (hours of Enddatum) + 1
							
						end if
						
						-- Ende der Anpassung der Zeit an die Zeitzone Sommer- / Winterzeit
						
						tell application "Calendar"
							tell calendar WelcherKalender
								
								make new event with properties {summary:NameDesEvents, start date:Anfangsdatum, end date:Enddatum, description:NotizenDesEvents, location:OrtDesEvents, allday event:false}
							end tell
						end tell
					end if
					set ZeileStart to ZeileStart + 1
				end repeat
				
			end tell
		end tell
	end tell
end tell

set theDialogText to "Alle " & WievieleZeilen & " Kalenderevents wurden eingepflegt!"
display dialog theDialogText
--> Result: {button returned:"OK"}

#6

Glad I could help. :grinning: