.ical standard format for Outlook and Google Calendar? - icalendar

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 10.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Mount view
DTSTART:20150310T01:00:00Z
LOCATION:CHRIS NISWANDEE BITBOOST TUCSON Alabama 85728
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Mount view
DTSTART:20150310T01:00:00Z
LOCATION:CHRIS NISWANDEE BITBOOST TUCSON Alabama 85728
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Reiver view
DTSTART:20150311T13:25:59Z
LOCATION:100 MAIN ST PO BOX 1022 SEATTLE Hawaii 98104
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Reiver view
DTSTART:20150312T11:30:26Z
LOCATION:The Honorable Charles W. Anderson (Dear Mr. Ambassador:) 2050 Bamako Place DC Washington 20521-2050
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Site seeing
DTSTART:20150312T15:50:23Z
LOCATION:The Honorable Charles W. Anderson (Dear Mr. Ambassador:) 2050 Bamako Place DC Washington 20521-2050
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
BEGIN:VEVENT
TZID:Eastern Time Zone
SUMMARY:Breakfast
DTSTART:20150315T23:55:13Z
LOCATION:1500 N Congress Ave #3E18 Austin Texas 78701
SEQUENCE:0
DESCRIPTION:Spring is one of the four conventional temperate seasons, following winter and preceding summer. There are various technical definitions of spring, but local usage of the term varies according to local climate, cultures and customs.
END:VEVENT
END:VCALENDAR
The above .ics file is workign fine on Outlook, but when I import to Google Calendar, the event start time shows an incorrect value.
What is missing from the above .ics file?
Can anyone provide a standard .ics file format with a clear example?
Thank you.

The DTSTART format should look like
DTSTART:20150310T010000Z
Then, for each event, you have a TZID property which is illegal within a VEVENT.
But are your DTSTART expressed in zulu (utc) time or in some local timezone ?

Related

What is the exact meaning of TZOFFSETFROM and TZOFFSETTO and how to calculate/use it?

I'm looking for a profound explanation what exactly the difference between TZOFFSETFROM and TZOFFSETTO in an iCalendar description is and how to calculate it.
While it is described here: https://www.rfc-editor.org/rfc/rfc5545#section-3.6.5 [Page 65] I can't wrap my head around the meaning and especially how to calculate it.
I have a list of all timezones and their related UTC_offset_StandardTime and UTC_offset_DaylightSavingTime but there is no "…onset…"-time.
While there is a somehow answer https://stackoverflow.com/a/3872214 I can't find a resource which proves that this right.
What am I missing?
Re: "How to calculate the timezone offset":
It is not 'calculated', but rather looked up - most systems have this information built in using the Olson timezone database, and kept (hopefully) up to date. The systems or languages usually have a function to get the offset for a given date and time. EG:
in php https://www.php.net/manual/en/datetime.getoffset.php. or one can get all the transitions to output to a VTIMEZONE https://www.php.net/manual/en/datetimezone.gettransitions.php
general comment here https://en.wikipedia.org/wiki/Time_zone#Computer_systems
Most systems maintain such a db. Usually there is a recurring rule that always is so, however countries and areas may change the date of daylight saving change. See https://en.wikipedia.org/wiki/Daylight_saving_time_in_Australia#Western_Australia and changes made for the Olympics. This would mean an extra set of VTIMEZONE DST transition definitions for those areas, with DTSTARTS and UNTIL's on any recurring rules to indicate over what years they apply or do not apply.
Now the .ics specification says we must include these timezone transitions - the daylight saving changes in a VTIMEZONE definition in the file.
That leads us to your other question:
RE: what is TZOFFSETFROM and TZOFFSETTO?
They are literally for each transition date generated by the RRULE (or just a date if not recurring if it was a one-off), relative to UTC or GMT:
the OFFSET FROM which a daylight saving change is coming and
the OFFSET TO which a daylight saving change is going
Take the New York 2021 daylight savings change on 14 March. The timezone offset is -5. After 14 march 2021 2 am, the timezoneoffset will be -4. See https://www.timeanddate.com/time/zone/usa/new-york-state.
So If we look at what google calendar outputs, we see that on the second sunday of march at 2am, Daylight saving begins, NY goes
FROM -05 and
TO -04.
Then when they revert to Standard Time on the 1st sunday in November, NY goes
FROM an offset of -04 and
TO an offset of -05.
NOTE that both (a FROM and a TO offset) are required because the change is NOT always by an hour. Sometimes the change may be 30 minutes. See https://www.timeanddate.com/time/time-zones-interesting.html and scroll down near the bottom. You'll see Lord Howe Island had a 1/2 hour change and further down under 'Historic half hour offsets' what North Korea did in 2015 and Venezuela in 2016.
Google Calendar New York example:
BEGIN:VTIMEZONE
TZID: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=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE

Some of deleted occurrence of recurring event doesn't comes under EXDATE

BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Test
TRANSP:OPAQUE
ATTENDEE;CUTYPE=INDIVIDUAL;EMAIL=a#icloud.com;PARTSTAT=ACCEPTED;
ROLE=CHAIR;CN=a:/aMzg2Mzc2MTQzODYzNzYxNBljuJkfI_9Sr7UoBKqc9uB4hzRY_BLyjaYyqorZZI2N/principal/
ATTENDEE;CUTYPE=INDIVIDUAL;EMAIL=jag#icloud.com;
PARTSTAT=ACCEPTED;X-CALENDARSERVER-DTSTAMP=20170629T173339Z;CN=jag:/aNDM3NzY5NTU0Mzc3Njk1NYeGQfswrR4swF97f86hXgEy6_Ht3psyYKknwa5ed2iV/principal/
UID:4CF18F94-CFB0-4EC8-8CA3-13BD88BE3009
DTSTART;TZID=America/Los_Angeles:20170530T183000
DTEND;TZID=America/Los_Angeles:20170530T220000
RRULE:FREQ=WEEKLY
EXDATE;TZID=America/Los_Angeles:20170711T183000
EXDATE;TZID=America/Los_Angeles:20170627T183000
EXDATE;TZID=America/Los_Angeles:20170620T183000
END:VEVENT
BEGIN:VEVENT
SUMMARY:Test
TRANSP:OPAQUE
ATTENDEE;CUTYPE=INDIVIDUAL;EMAIL=a#icloud.com;PARTSTAT=ACCEPTED;
ROLE=CHAIR;CN=a: /aMzg2Mzc2MTQzODYzNzYxNBljuJkfI_9Sr7UoBKqc9uB4hzRY_BLyjaYyqorZZI2N/principal/
ATTENDEE;CUTYPE=INDIVIDUAL;EMAIL=jag#icloud.com;
PARTSTAT=DECLINED;X-CALENDARSERVER-DTSTAMP=20170629T173339Z;
CN=jag:/aNDM3NzY5NTU0Mzc3Njk1NYeGQfswrR4swF97f86hXgEy6_Ht3psyYKknwa5ed2iV/principal/
UID:4CF18F94-CFB0-4EC8-8CA3-13BD88BE3009
DTSTART;TZID=America/Los_Angeles:20170606T183000
DTEND;TZID=America/Los_Angeles:20170606T220000
RECURRENCE-ID;TZID=America/Los_Angeles:20170606T183000
END:VEVENT
END:VCALENDAR
Here, I have weekly recurring meeting for every Tuesday from 6:30 PM to 10:00 PM. I have deleted the single occurrence for 06/06/2017. But when I fetch meetings it gives deleted occurrence i.e 06/06/2017 6:30 PM to 10:30 PM which it shouldn't be. While 20/06, 27/06 and 11/07 comes in ex date which is fine. My question is that why 06/06 is not in ex date even after deletion like other deleted dates ?
Thanks in advance

iCalendar: Event with multiple dates?

I have what I believe to be a nearly minimal calendar with 2 test events:
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:Q1
DTSTAMP:20170504
SUMMARY:Testing Description 1
DTSTART:20170510
DTEND:20170510
DESCRIPTION:Testing Stuff 1
END:VEVENT
BEGIN:VEVENT
UID:Q2
DTSTAMP:20170504
SUMMARY:Testing Summary 1
DTSTART:20170512
DTEND:20170512
DESCRIPTION:Testing Description 1
END:VEVENT
END:VCALENDAR
As you see, the plan is for the 2 events to have the same Summary & Description. That is because I would like it to be a 2-day event.
Does the iCalendar format actually have a proper multi-date event? By multi-date I mean:
not necessarily consecutive dates
multiple dates without a particular pattern (not actually recurring)
I see that iCalendar has quite clever recurrence patterns (http://www.kanzaki.com/docs/ical/rrule.html), but the one thing I can’t find is a rule for arbitrary dates.
To do so, you can have one single VEVENT with DTSTART/DTEND corresponding to the first instance, and an RDATE property with multiple values corresponding to the DTSTART of each of the instances. See https://www.rfc-editor.org/rfc/rfc5545#section-3.8.5.2
An alternative would be to keep two events as you have done, but to link them via a RELATED-TO property: https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.5
Now, in both cases (especially for RELATED-TO), generic clients may not always understand or take advantage of those properties.

Appointment in calendars use wrong time from ics file

I am generating a .ics file. When I import it to a calendar app (such as the on on OSX or iOS) it says:
20:00 to 21:00
18:00 to 19:00 (GMT)
But I need to have the time of the appointment to be 18:00 to 19:00 by default (GMT time). How can I do it?
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:xxx
X-WR-TIMEZONE:Europe/Zurich
X-WR-CALDESC:
BEGIN:VTIMEZONE
TZID:Europe/Zurich
X-LIC-LOCATION:Europe/Zurich
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
Event:
BEGIN:VEVENT
DTSTART:20140929T180000Z
DTEND:20140929T190000Z
DTSTAMP:20141001T223333Z
UID:542c651df4095
DESCRIPTION:Keine
SUMMARY:Mindblowers
LOCATION:
URL;VALUE=URI:xxx
END:VEVENT
most calendar applications will display in the timezone that you have set in the app. So to see times in GMT time, set the timezone of the app to GMT.
Alternatively you may not really be meaning that you want 18:00 to 19:00 (GMT) but that you want 18:00 to 19:00 no matter what timezone the app is in. This is called a 'floating time' (like an alarm that wakes you at 7am no matter what city or timezone you are in, no at 7am back home).
https://www.rfc-editor.org/rfc/rfc5545#page-32
For example, the following represents January 18, 1998, at
11 PM:
19980118T230000
DATE-TIME values of this type are said to be "floating" and are
not bound to any time zone in particular. They are used to
represent the same hour, minute, and second value regardless of
which time zone is currently being observed.

How do I make an iCal feed for holidays moved to adjacent weekdays?

I'm trying to make an iCal feed (RFC 2445) for work holidays that won't need yearly updates, by listing holidays per their definition, rather than which dates they occur on on particular years.
Holidays like Memorial day (last Monday in May) of course don't need any special treatment beyond
BEGIN:VEVENT
DTSTAMP:20130210T211949Z
UID:20130210-memorial-day#usa.gov
DTSTART;VALUE=DATE:20130527
DTEND;VALUE=DATE:20130527
SUMMARY:Memorial Day
RRULE:FREQ=YEARLY;BYMONTH=5;BYDAY=-1MO;WKST=SU
END:VEVENT
...but when it comes to date-based holidays like New Year's Day, how does one encode the day slip on weekend Jan 1sts?
you should be aware that even though google calendar follows RFC2445, it has been obsoleted by RFC5545 which has made the EXRULE obsolete (deprecated features from RFC2445).
in the case of UK new year, it is:
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:pyICSParser
BEGIN:VEVENT
DTSTART;VALUE=DATE:20070101
RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=MO,TU,WE,TH,FR;BYMONTHDAY=1,2,3;BYSETPOS=1
UID:UIDnewyear_SO14805248#stackeroverflow.com
DTSTAMP:19970714T170000Z
SUMMARY: new year
END:VEVENT
END:VCALENDAR
which works like a charm under google calendar, outlook.com(/hotmail/...), yahoo calendars and on iOS devices synching from a Google Calendar.
UPDATE: for the USA new year
it would be a combination of 2 RRULE (RFC says SHOULD NOT occur more than once which seems to leave the possibility of 2 RRULE by event:
RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=MO,TU,WE,TH,FR;BYMONTHDAY=1,2;BYSETPOS=1
RRULE:FREQ=YEARLY;BYMONTH=12;BYDAY=FR;BYMONTHDAY=-1
Google Calendar supports it but looks like yahoo and hotmail/outlook.com don't, so 2 events would need to be created (one with each RRULE). If needed the use of RELATED-TO property could help keep track of their relations.
NOTE: The following answer demonstrates how to do it with a deprecated RFC! I am leaving it for reference, in case anyone ever needs to. See the proper answer for more useful facts!
You can do this by adding corresponding yearly repeating adjacent-Friday and adjacent-Monday rules that only show up years where the date has the corresponding weekday:
BEGIN:VEVENT
DTSTAMP:20130210T211949Z
UID:20130210-new-years-day-less-1#usa.gov
DTSTART;VALUE=DATE:20121231
DTEND;VALUE=DATE:20121231
SUMMARY:New Year’s Day (moved from a Saturday)
RRULE:FREQ=YEARLY;BYMONTH=12;BYMONTHDAY=31
EXRULE:FREQ=YEARLY;BYMONTH=12;BYMONTHDAY=31;BYDAY=MO,TU,WE,TH,SA,SU
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20130210T211949Z
UID:20130210-new-years-day-plus-1#usa.gov
DTSTART;VALUE=DATE:20130102
DTEND;VALUE=DATE:20130102
SUMMARY:New Year’s Day (moved from a Sunday)
RRULE:FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=2
EXRULE:FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=2;BYDAY=TU,WE,TH,FR,SA,SU
END:VEVENT
Together with the original event (you can similarly filter this one for BYDAY=MO,TU,WE,TH,FR if you don't want the actual holiday to show up in your feed), you cover all years without getting false positives on years where there was no need to move the time off to a weekday:
BEGIN:VEVENT
DTSTAMP:20130210T211949Z
UID:20130210-new-years-day#usa.gov
DTSTART;VALUE=DATE:20130101
DTEND;VALUE=DATE:20130101
SUMMARY:New Year’s Day
RRULE:FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=1
END:VEVENT
Google Calendar happily consumes and understands my example iCalendar feed. Current iCal (and iOS devices synced from a Google Calendar that imported this feed) unfortunately are a little buggy (filed as  bug 13188350 [link probably only works for the reporter]), and fail to apply the specified weekday filters.
But hopefully that gets fixed too, some time soon.