parsing ics file - recurring events timezone issue - bash

This is a basic.ics file containing a recurring event and a non-recurring event
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:GreekMan
X-WR-TIMEZONE:Asia/Nicosia
BEGIN:VTIMEZONE
TZID:Europe/Moscow
X-LIC-LOCATION:Europe/Moscow
BEGIN:STANDARD
TZOFFSETFROM:+0300
TZOFFSETTO:+0300
TZNAME:MSK
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:Asia/Nicosia
X-LIC-LOCATION:Asia/Nicosia
BEGIN:STANDARD
TZOFFSETFROM:+0300
TZOFFSETTO:+0200
TZNAME:EET
DTSTART:19701025T040000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0200
TZOFFSETTO:+0300
TZNAME:EEST
DTSTART:19700329T030000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART:20221110T140000Z
DTEND:20221110T143000Z
DTSTAMP:20221110T093950Z
UID:52kaiifeon2cdil0m6ln6m4cf6#google.com
CREATED:20221110T091122Z
LAST-MODIFIED:20221110T091122Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:non recurring event 1600
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Asia/Nicosia:20221110T130000
DTEND;TZID=Asia/Nicosia:20221110T133000
RRULE:FREQ=WEEKLY;BYDAY=TH
DTSTAMP:20221110T093950Z
UID:4ponmapnn5o6bj0fep6kfplcf4#google.com
CREATED:20221110T091051Z
DESCRIPTION:
LAST-MODIFIED:20221110T091101Z
LOCATION:
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:recurring event 1300
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
I download this file with wget and convert it to a table using this command
awk 'BEGIN{FS=":"}/^DTSTART/{dtstart=$2}/^SUMMARY/{summary=$2}/^END:VEVENT/{print substr(dtstart,7,2)"/"substr(dtstart,5,2)"/"substr(dtstart,1,4),sprintf("%02d",substr(dtstart,10,2)'+2')":"substr(dtstart,12,2),summary}' basic.ics
This is the output. As you can see the recurring event is showing the wrong time.
10/11/2022 16:00 non recurring event 1600
10/11/2022 15:00 recurring event 1300
google calendar shows the time in UTC+0, so as you can see in the above command I add 2 hours to each event to make it UTC+2.
The problem is that recurring events include the timezone on DTSTART, so those events don't have to be corrected.
How can I modify the command to avoid adding 2 hours to recurring events?

Related

how to delete a series of events from recurring set using ics file?

Im trying to delete a series of dates like google or zoom does ("delete this and following occurrences") but cant seem to delete them all
here is the code I'm using to do so
RECURRENCE-ID;RANGE=THISANDFUTURE;TZID=America/New_York:20230221T100000Z
I saw few people recommending to use UNTIL in the range parameter for recurrence-id but cannot find any syntax or working example.
Thanks in advance
Full code for creating recurring event:
BEGIN:VCALENDAR
VERSION:2.0
PRODID://Events//iCal 2.1//EN
METHOD:REQUEST
X-WR-CALNAME:Event Calendar
X-WR-TIMEZONE:America/New_York
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:America/New_York
TZURL:http://tzurl.org/zoneinfo-outlook/America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
TRANSP:OPAQUE
CREATED:20221221T094254Z
UID:TESTSC20221221094254
DTEND;TZID=America/New_York:20221226T110000
SUMMARY:deadline approaching Event
LOCATION;ENCODING=QUOTED-PRINTABLE:Virtual Meeting
DTSTART;TZID=America/New_York:20221226T100000
DTSTAMP:20221221T094254Z
ORGANIZER;CN=Events:mailto:events#abc.org
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=abc#abc.org;X-NUM-GUESTS=0:mailto:abc#abc.org
STATUS:CONFIRMED
DESCRIPTION:A. Want to join the meeting from your computer, tablet or smartphone?\n go to https://zoom.us/
SEQUENCE:0
RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20230228T110000Z
BEGIN:VALARM
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT10M
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR
Full code I use for deleting:
VERSION:2.0
PRODID://Events//iCal 2.1//EN
METHOD:CANCEL
X-WR-CALNAME:Event Calendar
X-WR-TIMEZONE:America/New_York
CALSCALE:GREGORIAN
BEGIN:VEVENT
TRANSP:OPAQUE
CREATED:20221221T145554Z
UID:TESTSC20221221094254
DTSTART;TZID=America/New_York:20221226T100000
DTEND;TZID=America/New_York:20221226T110000
SUMMARY:Event: deadline approaching Cancelled
LOCATION;ENCODING=QUOTED-PRINTABLE:Virtual Meeting
DTSTAMP:20221221T145554Z
ORGANIZER;CN=Events:mailto:events#abc.org
RECURRENCE-ID;RANGE=THISANDFUTURE;TZID=America/New_York:20230221T100000Z
SEQUENCE:0
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=abc#abc.org;X-NUM-GUESTS=0:mailto:abc#abc.org
STATUS:CANCELLED
DESCRIPTION:This meeting has been deleted. Please contact HQ for scheduling a new meeting or more information about this.
END:VEVENT
END:VCALENDAR```

Cannot cancel ical event (dreaded "not supported calendar message.ics")

I'm writing a system in Python that is using the icalendar library to generate ical invites. Those work fantastically, but if I try to send out a cancellation Outlook just displays the dreaded "not supported calendar message.ics". I originally had this issue with the invite, but solved it by fixing my date formatting.
Here is the initial invite:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//myapp//myapp.example.com//
METHOD:REQUEST
BEGIN:VEVENT
SUMMARY:Weekly Review Meeting
DTSTART;VALUE=DATE-TIME:20200331T190000Z
DTEND;VALUE=DATE-TIME:20200331T200000Z
DTSTAMP;VALUE=DATE-TIME:20200325T193007Z
UID:1#myapp
SEQUENCE:0
ATTENDEE:me#example.com
CATEGORY:EVENT
CLASS:PUBLIC
DESCRIPTION:bla bla
LOCATION:Webex
ORGANIZER:donotreply#example.com
PRIORITY:5
STATUS:CONFIRMED
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR
And then the cancellation:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//myapp//myapp.example.com//
METHOD:CANCEL
BEGIN:VEVENT
SUMMARY:Weekly Review Meeting
DTSTART;VALUE=DATE-TIME:20200331T190000Z
DTEND;VALUE=DATE-TIME:20200331T200000Z
DTSTAMP;VALUE=DATE-TIME:20200325T193011Z
UID:1#myapp
SEQUENCE:1
ATTENDEE:me#example.com
CATEGORY:EVENT
CLASS:PUBLIC
DESCRIPTION:
LOCATION:Webex
ORGANIZER:donotreply#example.com
PRIORITY:5
STATUS:CANCELLED
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR
The same code generates both and sets the METHOD and STATUS differently (DESCRIPTION also differs). I send a SEQUENCE of 0 for the invite and 1 for the cancellation. The UIDs are always consistent between the matching pair. What am I missing?
I ended up solving this myself. I will share my learnings for posterity.
The MIME type in the email needs to be set with method=CANCEL as well. This was ultimately my issue. method in the MIME type needs to match METHOD in the ical file and both are required for Outlook to process it correctly.
SEQUENCE should not be incremented for cancellation, just for update.
I also updated all addresses (ORGANIZER and ATTENDEE) to include mailto:, but this does not appear to be strictly necessary.

Outlook live ICS calendar off by 1 hour

BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-WR-CALNAME:Test Cal
X-WR-CALDESC:2016-2017
X-WR-TIMEZONE:America/Toronto
BEGIN:VTIMEZONE
TZID:America/Toronto
X-LIC-LOCATION:America/Toronto
BEGIN:STANDARD
DTSTART:20161106T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20170312T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:20161020T235802EDT-7919w7sZDz
DTSTAMP:20161021T035802Z
DESCRIPTION:Details Sat Oct 15\, 2016 6:00pm - 7:00 pm
DTSTART;TZID=America/Toronto:20161015T180000
DTEND;TZID=America/Toronto:20161015T190000
LOCATION:Hockey Arena
SEQUENCE:1
SUMMARY:Game
END:VEVENT
END:VCALENDAR
This calendar when subscribed to in Gmail, iPhone or iCloud show the correct time of this even at 6pm. However Outlook Live displays this event one hour later : 7pm to 8pm. Why would this be? The dates and times are correct after daylights savings time change. So after Nov 5th, the times are correct.
Dont know where you got this VTIMEZONE definition but it has the DST starting only in 2017.
Try with something like:
BEGIN:VTIMEZONE
TZID:America/Toronto
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:20081102T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:20080309T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
I'm assuming that the empty lines were added only in your stackoverflow post.

iCal not correct time with google calender

I have a problem with my ical file.
In outlook I get the correct date 10.12.2015 20:00 - 10.12.2015 22:00.
In my Google calendar I got the date 10.12.2015 20:00 - 23.00.
The following is my ical file:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:*****
METHOD:PUBLISH
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:*****
ORGANIZER;CN="admin":MAILTO:*****
LOCATION:*****
SUMMARY:*****
DESCRIPTION:
CLASS:PUBLIC
DTSTART;TZID=Europe/Berlin:20151210T200800
DTEND;TZID=Europe/Berlin:20151210T220800
END:VEVENT
END:VCALENDAR
Try using a DURATION property instead of DTEND.
DTSTART;TZID=Europe/Berlin:20151210T200800
DURATION:PT2H
Well it looks like both clients are somehow rounding the time of the event from 20h08 / 22h08 to full hours. Given that the event runs after 22h, it makes as much sense to round it to 23h00: you probably don't want the user to doublebook the calendar by adding another event at 22h00, thinking that that slot is free when it is not (but that is no longer visible to the user).

Update an event in Outlook 2007 with an iCalendar file

There is a previous thread with this question, and hints at an answer, but I could not get it to work.
I have an ICS file. It validates. It looks like this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//WA//FRWEB//EN
BEGIN:VEVENT
UID:FRICAL201
SEQUENCE:0
DTSTAMP:20081108T151809Z
DTSTART:20081109T121200
SUMMARY:11/9/2008 12:12:00 PM TRIP FROM JFK AIRPORT (JFK)
LOCATION:JFK AIRPORT (JFK)
END:VEVENT
END:VCALENDAR
I double-click it and it goes into Outlook 2007 perfectly.
Then, I double-click another ICS file that looks like this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//WA//FRWEB//EN
BEGIN:VEVENT
METHOD:REQUEST
UID:FRICAL201
SEQUENCE:1
DTSTAMP:20081108T161809Z
DTSTART:20081109T121300
SUMMARY:11/9/2008 12:13:00 PM TRIP FROM JFK AIRPORT (JFK)
LOCATION:JFK AIRPORT (JFK)
END:VEVENT
END:VCALENDAR
As explained in the rfc, the UID is the same and the sequence number is one greater, so I expect outlook to update my previous event entry, but all it does is insert a second one.
How can I formulate the ICS file so that Outlook knows to update the event? The original poster in the thread I referenced above said he got it to respond with METHOD and ORGANIZER but in my experience METHOD has no effect and ORGANIZER causes undesirable behavior where Outlook wants to email the event to someone. I just want it to update the calendar.
I got a hold of Tom Carter, the guy who started the original thread. He had a working example with a request followed by a cancellation. What I had wrong was my METHOD was inside my VEVENT when it should have been outside. So here is a working update!
Original:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//WA//FRWEB//EN
METHOD:REQUEST
BEGIN:VEVENT
UID:FRICAL201
SEQUENCE:0
DTSTAMP:20081108T151809Z
ORGANIZER:donotreply#test.com
DTSTART:20081109T121200
SUMMARY:11/9/2008 12:12:00 PM TRIP FROM JFK AIRPORT (JFK)
LOCATION:JFK AIRPORT (JFK)
END:VEVENT
END:VCALENDAR
Update:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//WA//FRWEB//EN
METHOD:REQUEST
BEGIN:VEVENT
UID:FRICAL201
SEQUENCE:1
DTSTAMP:20081108T161809Z
ORGANIZER:donotreply#test.com
DTSTART:20081109T121300
SUMMARY:11/9/2008 12:13:00 PM TRIP FROM JFK AIRPORT (JFK)
LOCATION:JFK AIRPORT (JFK)
END:VEVENT
END:VCALENDAR
All I did was add the request method (in the correct spot!), and an organizer.

Resources