diff --git a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java index a7c058380fe267e3f55b902aa4c4a305f62a5ee0..75b2ef08dc0eb918ded4db1c3a46ee85a8e301ee 100644 --- a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java +++ b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java @@ -701,14 +701,22 @@ public class ICalFileCalendarManager implements CalendarManager, InitializingBea // check all day event first boolean isAllDay = false; Parameter dateParameter = event.getProperties().getProperty(Property.DTSTART).getParameters().getParameter(Value.DATE.getName()); - if (dateParameter != null) isAllDay = true; + if (dateParameter != null) { + isAllDay = true; + } else if(start != null && end != null && (end.getTime() - start.getTime()) == (24 * 60 * 60 * 1000)) { + //check that start has no hour, no minute and no second + java.util.Calendar cal = java.util.Calendar.getInstance(); + cal.setTime(start); + isAllDay = cal.get(java.util.Calendar.HOUR_OF_DAY) == 0 && cal.get(java.util.Calendar.MINUTE) == 0 + && cal.get(java.util.Calendar.SECOND) == 0 && cal.get(java.util.Calendar.MILLISECOND) == 0; + } if (isAllDay) { //Make sure the time of the dates are 00:00 localtime because DATE fields in iCal are GMT 00:00 //Note that start date and end date can have different offset because of daylight saving switch java.util.TimeZone timezone = java.util.GregorianCalendar.getInstance().getTimeZone(); start = new Date(start.getTime() - timezone.getOffset(start.getTime())); - end = new Date(end.getTime() - timezone.getOffset(end.getTime())); + end = new Date(end.getTime() - timezone.getOffset(end.getTime())); // adjust end date: ICal sets end dates to the next day end = new Date(end.getTime() - (1000 * 60 * 60 * 24)); diff --git a/src/test/java/org/olat/commons/calendar/CalendarImportTest.java b/src/test/java/org/olat/commons/calendar/CalendarImportTest.java index 97e9bb8bfe4bd0bdf5ddcda92fac8e98d5d2af2d..a4364f3b1dfd6bd6ff2fc9808f5998798b4bc2c1 100644 --- a/src/test/java/org/olat/commons/calendar/CalendarImportTest.java +++ b/src/test/java/org/olat/commons/calendar/CalendarImportTest.java @@ -146,16 +146,13 @@ public class CalendarImportTest { Period period = new Period(start, end); PeriodList pList = rootEvent.calculateRecurrenceSet(period); for(Object obj:pList) { - Period p = (Period)obj; - System.out.println("Period: " + p.getStart()); + Period p = (Period)obj; + System.out.println("Period: " + p.getStart()); } RecurrenceId recurrenceId = exceptionEvent.getRecurrenceId(); Date recurrenceDate = recurrenceId.getDate(); System.out.println("Recurrence: " + recurrenceDate); - exceptionEvent.getSequence(); } - - } diff --git a/src/test/java/org/olat/commons/calendar/manager/ICalFileCalendarManagerTest.java b/src/test/java/org/olat/commons/calendar/manager/ICalFileCalendarManagerTest.java index 0d0be10ff4e4203235496c42d0c48bb198442373..3562720a1e765028decccf8eb7786aa6de1b025d 100644 --- a/src/test/java/org/olat/commons/calendar/manager/ICalFileCalendarManagerTest.java +++ b/src/test/java/org/olat/commons/calendar/manager/ICalFileCalendarManagerTest.java @@ -583,7 +583,45 @@ public class ICalFileCalendarManagerTest extends OlatTestCase { .importCalendar(test, calendarName, CalendarManager.TYPE_USER, calendarFile); List<KalendarEvent> events = importedCalendar.getKalendar().getEvents(); Assert.assertEquals(2, events.size()); - + } + + @Test + public void testImportICal_outlookFullDay() throws URISyntaxException, IOException { + Identity test = JunitTestHelper.createAndPersistIdentityAsRndUser("ur2-"); + URL calendarUrl = ICalFileCalendarManagerTest.class.getResource("Fullday_outlook.ics"); + File calendarFile = new File(calendarUrl.toURI()); + String calendarName = UUID.randomUUID().toString().replace("-", ""); + + KalendarRenderWrapper importedCalendar = importCalendarManager + .importCalendar(test, calendarName, CalendarManager.TYPE_USER, calendarFile); + List<KalendarEvent> events = importedCalendar.getKalendar().getEvents(); + Assert.assertEquals(1, events.size()); + + KalendarEvent event = events.get(0); + Assert.assertTrue(event.isAllDayEvent()); + } + + @Test + public void testImportICal_icalFullDay() throws URISyntaxException, IOException { + Identity test = JunitTestHelper.createAndPersistIdentityAsRndUser("ur3-"); + URL calendarUrl = ICalFileCalendarManagerTest.class.getResource("Fullday_ical.ics"); + File calendarFile = new File(calendarUrl.toURI()); + String calendarName = UUID.randomUUID().toString().replace("-", ""); + + KalendarRenderWrapper importedCalendar = importCalendarManager + .importCalendar(test, calendarName, CalendarManager.TYPE_USER, calendarFile); + List<KalendarEvent> events = importedCalendar.getKalendar().getEvents(); + Assert.assertEquals(3, events.size()); + + // 24 hours but on 2 days + KalendarEvent on2days = importedCalendar.getKalendar().getEvent("EFE10508-15B0-4FCE-A258-37BA642B760D", null); + Assert.assertFalse(on2days.isAllDayEvent()); + // real all day with the iCal standard + KalendarEvent allDay = importedCalendar.getKalendar().getEvent("14C0ACCD-AC0B-4B10-A448-0BF129492091", null); + Assert.assertTrue(allDay.isAllDayEvent()); + // almost a full day bit it miss one minute + KalendarEvent longDay = importedCalendar.getKalendar().getEvent("C562E736-DCFF-4002-9E5B-77D891D4A322", null); + Assert.assertFalse(longDay.isAllDayEvent()); } /** diff --git a/src/test/resources/org/olat/commons/calendar/manager/Fullday_ical.ics b/src/test/resources/org/olat/commons/calendar/manager/Fullday_ical.ics new file mode 100644 index 0000000000000000000000000000000000000000..1c404b552caadcf6cabeb20bc2ed52033553b01e --- /dev/null +++ b/src/test/resources/org/olat/commons/calendar/manager/Fullday_ical.ics @@ -0,0 +1,68 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +VERSION:2.0 +X-WR-CALNAME:Test +PRODID:-//Apple Inc.//Mac OS X 10.12.6//EN +X-APPLE-CALENDAR-COLOR:#1BADF8 +X-WR-TIMEZONE:Europe/Zurich +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Europe/Zurich +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +DTSTART:19810329T020000 +TZNAME:UTC+2 +TZOFFSETTO:+0200 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +DTSTART:19961027T030000 +TZNAME:UTC+1 +TZOFFSETTO:+0100 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20170921T093443Z +UID:14C0ACCD-AC0B-4B10-A448-0BF129492091 +DTEND;VALUE=DATE:20170919 +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +SUMMARY:Fullday +DTSTART;VALUE=DATE:20170918 +DTSTAMP:20170921T134739Z +SEQUENCE:0 +BEGIN:VALARM +X-WR-ALARMUID:1A664771-C654-4662-8E4E-F7ABDC32CBCD +UID:1A664771-C654-4662-8E4E-F7ABDC32CBCD +TRIGGER:-PT15H +ATTACH;VALUE=URI:Basso +X-APPLE-LOCAL-DEFAULT-ALARM:TRUE +ACTION:AUDIO +X-APPLE-DEFAULT-ALARM:TRUE +END:VALARM +END:VEVENT +BEGIN:VEVENT +CREATED:20170921T134346Z +UID:C562E736-DCFF-4002-9E5B-77D891D4A322 +DTEND;TZID=Europe/Zurich:20170919T235900 +TRANSP:OPAQUE +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +SUMMARY:Long day +DTSTART;TZID=Europe/Zurich:20170919T000000 +DTSTAMP:20170921T134745Z +SEQUENCE:0 +END:VEVENT +BEGIN:VEVENT +CREATED:20170921T134625Z +UID:EFE10508-15B0-4FCE-A258-37BA642B760D +DTEND;TZID=Europe/Zurich:20170921T010000 +TRANSP:OPAQUE +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +SUMMARY:24Hour but 2 days +DTSTART;TZID=Europe/Zurich:20170920T010000 +DTSTAMP:20170921T134754Z +SEQUENCE:0 +END:VEVENT +END:VCALENDAR diff --git a/src/test/resources/org/olat/commons/calendar/manager/Fullday_outlook.ics b/src/test/resources/org/olat/commons/calendar/manager/Fullday_outlook.ics new file mode 100644 index 0000000000000000000000000000000000000000..c9df5c455f9be709bda40b0017f8c4815079510b --- /dev/null +++ b/src/test/resources/org/olat/commons/calendar/manager/Fullday_outlook.ics @@ -0,0 +1,42 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +PRODID:Microsoft Exchange Server 2010 +VERSION:2.0 +X-WR-CALNAME:MFLVFL_17 +BEGIN:VTIMEZONE +TZID:W. Europe Standard Time +BEGIN:STANDARD +DTSTART:16010101T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10 +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:16010101T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3 +END:DAYLIGHT +END:VTIMEZONE +BEGIN:VEVENT +DESCRIPTION:Werbung_2016\nDistribution_2016\nMarketing_2015_2016\nVerkaufsplanung_2016\nNur AD Rechtskunde_2015_2016\n\n\n +SUMMARY:VFL_17_Abgabetermin +DTSTART;TZID=W. Europe Standard Time:20171004T000000 +DTEND;TZID=W. Europe Standard Time:20171005T000000 +UID:040000008200E00074C5B7101A82E00800000000002428D0D920D301000000000000000010000000858708CB47EBDE45AE4CFBD30388C9B6 +CLASS:PUBLIC +PRIORITY:5 +DTSTAMP:20170921T085012Z +TRANSP:OPAQUE +STATUS:CONFIRMED +SEQUENCE:0 +LOCATION: +X-MICROSOFT-CDO-APPT-SEQUENCE:0 +X-MICROSOFT-CDO-BUSYSTATUS:FREE +X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +X-MICROSOFT-CDO-IMPORTANCE:1 +X-MICROSOFT-CDO-INSTTYPE:0 +X-MICROSOFT-DISALLOW-COUNTER:FALSE +END:VEVENT +END:VCALENDAR \ No newline at end of file