I know I'm late on this, but just wanted to provide a solution with iCal4j for anyone coming up on this issue.
Indeed time zones are not implicitly managed in iCalendar standard, you must explicitly add the VTIMEZONE
definition in your ICS file (RFC). You cannot just use the time zone identifier (TZID
).
You can refer to this answer for an explanation about why time zone information is needed.
So here is an example using iCal4j :
// get timezone
final TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
final TimeZone timezone = registry.getTimeZone("Europe/Zurich");
final VTimeZone tz = timezone.getVTimeZone();
// event start date
final java.util.Calendar startDate = new GregorianCalendar();
startDate.setTimeZone(timezone);
startDate.set(2016, java.util.Calendar.MARCH, 8, 9, 0, 0);
// event end date
final java.util.Calendar endDate = new GregorianCalendar();
endDate.setTimeZone(timezone);
endDate.set(2016, java.util.Calendar.MARCH, 8, 17, 0, 0);
// create event
final DateTime start = new DateTime(startDate.getTime(), timezone);
final DateTime end = new DateTime(endDate.getTime(), timezone);
final VEvent meeting = new VEvent(start, end, "Test");
meeting.getProperties().add(new RandomUidGenerator().generateUid());
meeting.getProperties().add(new Location("Somewhere"));
// create calendar
final net.fortuna.ical4j.model.Calendar icsCalendar = new net.fortuna.ical4j.model.Calendar();
icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
icsCalendar.getProperties().add(CalScale.GREGORIAN);
icsCalendar.getProperties().add(Version.VERSION_2_0);
// add the timezone definition <- this is what you are missing
icsCalendar.getComponents().add(tz);
// add event to calendar
icsCalendar.getComponents().add(meeting);
The important line in the one which adds the VTimeZone
component to the Calendar
. So you don't need to get the definition from a web service.
You can refer the iCal4j documentation.
Then you should end-up with something like this (for the Europe/Zurich
time zone) :
BEGIN:VCALENDAR
PRODID:-//Events Calendar//iCal4j 1.0//EN
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:20160307T231014Z
DTSTART;TZID=Europe/Zurich:20160308T090000
DTEND;TZID=Europe/Zurich:20160308T170000
SUMMARY:Test
TZID:Europe/Zurich
UID:45c269ed-dbc0-435e-bb3d-ba152dfbf0db
LOCATION:Somewhere
END:VEVENT
BEGIN:VTIMEZONE
TZID:Europe/Zurich
LAST-MODIFIED:20201011T015911Z
TZURL:http://tzurl.org/zoneinfo/Europe/Zurich
X-LIC-LOCATION:Europe/Zurich
X-PROLEPTIC-TZNAME:LMT
BEGIN:STANDARD
TZNAME:BMT
TZOFFSETFROM:+003408
TZOFFSETTO:+002946
DTSTART:18530716T000000
END:STANDARD
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+002946
TZOFFSETTO:+0100
DTSTART:18940601T000000
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19410505T010000
RRULE:FREQ=YEARLY;UNTIL=19420504T000000Z;BYMONTH=5;BYDAY=1MO
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19411006T020000
RRULE:FREQ=YEARLY;UNTIL=19421005T000000Z;BYMONTH=10;BYDAY=1MO
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19810329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19810927T030000
RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU
END:STANDARD
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
END:VCALENDAR