0

I work with an export from a Zimbra calendar and wold like to create a list of all events occurring on each day. The simplified calendar looks like this.

BEGIN:VCALENDAR
X-WR-CALNAME:Test-Parking
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:STANDARD
DTSTART:19710101T030000
TZOFFSETTO:+0100
TZOFFSETFROM:+0200
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
TZNAME:CET
END:STANDARD
END:VTIMEZONE

BEGIN:VEVENT
RRULE:FREQ=DAILY;COUNT=3;INTERVAL=1
SUMMARY:Day Event 3 Times
DTSTART;VALUE=DATE:20120911
DTEND;VALUE=DATE:20120912
END:VEVENT

BEGIN:VEVENT
SUMMARY:4 hours event
DTSTART;TZID="Europe/Berlin":20120911T090000
DTEND;TZID="Europe/Berlin":20120911T130000
END:VEVENT
END:VCALENDAR

Now i have written some lines of code to filter the events:

public class CalendarTester {

    private Calendar calendar;
    private TimeZoneRegistry registry;

    public static void main(String[] args) throws Exception {
        CalendarTester tester = new CalendarTester();
        tester.run();
    }

    private void run() throws IOException, ParserException, URISyntaxException,
            ParseException {
        readCalendar();
        TimeZone tz = registry.getTimeZone("Europe/Berlin");
        SimpleDateFormat formatter = new SimpleDateFormat();
        GregorianCalendar cal = new GregorianCalendar(2012,
                GregorianCalendar.SEPTEMBER, 10);
        cal.set(GregorianCalendar.HOUR_OF_DAY, 0);
        cal.set(GregorianCalendar.MINUTE, 0);
        cal.set(GregorianCalendar.SECOND, 0);
        cal.setTimeZone(tz);

        for (int i = 0; i < 5; i++) {
            Period p = new Period(new DateTime(cal.getTime()), new Dur(1, 0, 0,
                    0));
            p.setTimeZone(tz);
            Rule[] rules = new Rule[1];
            rules[0] = new PeriodRule(p);
            Filter f = new Filter(rules, Filter.MATCH_ALL);

            System.out.println("_____________");
            System.out.println(formatter.format(cal.getTime()));
            for (Object event : f.filter(calendar
                    .getComponents(Component.VEVENT))) {
                printEvent((VEvent) event, formatter);
            }
            cal.add(GregorianCalendar.DAY_OF_YEAR, 1);
        }
    }

    private void printEvent(VEvent event, SimpleDateFormat formatter) {
        System.out.println("Start: "
                + formatter.format(event.getStartDate().getDate()) + " End: "
                + formatter.format(event.getEndDate().getDate()) + " Summary: "
                + event.getSummary().getValue());
    }

    private void readCalendar() throws FileNotFoundException, IOException,
            ParserException {
        FileInputStream fin = new FileInputStream(
                "files/Recuring_Calendar_Entry_From_To.ics");

        CalendarBuilder builder = new CalendarBuilder();
        calendar = builder.build(fin);
        registry = builder.getRegistry();
    }

}

Now i get the Simple event correctly but the 3 time occuring one day event 4 times, because of the wrong start and end times.

_____________
10.09.12 01:00
_____________
11.09.12 01:00
Start: 11.09.12 02:00 End: 12.09.12 02:00 Summary: Day Event 3 Times
Start: 11.09.12 10:00 End: 11.09.12 14:00 Summary: 4 hours event
_____________
12.09.12 01:00
Start: 11.09.12 02:00 End: 12.09.12 02:00 Summary: Day Event 3 Times
_____________
13.09.12 01:00
Start: 11.09.12 02:00 End: 12.09.12 02:00 Summary: Day Event 3 Times
_____________
14.09.12 01:00
Start: 11.09.12 02:00 End: 12.09.12 02:00 Summary: Day Event 3 Times

So if anyone has an idea what i have to change at the import or at the filter, that i get all events in the same timezone.

Tanks for any suggestions, Cy


I did some tests to figure out what is going on. The start was the Tests for the filters in:

test/net/fortuna/ical4j/filter/PeriodRuleTest.java

If i create a new all day event like it is shown there everything is ok. If i add a recure roule the functionality is broken.

Recur recur = new Recur("FREQ=DAILY;COUNT=3;INTERVAL=1");
event.getProperties().add(new RRule(recur));

Now the Event matches for the starting date and on the following 3 days as it is shown in the sample above. If I set the COUNT=1 in the rule the event now matches 2 times. Maybe I do not understand the recurring rule? If I take a look at the web calendar (Zimbra) where I exported this events everything is like i expected.

Here you can see my test class

Cœur
  • 37,241
  • 25
  • 195
  • 267
Michael Klenk
  • 3,202
  • 2
  • 19
  • 19

1 Answers1

0

I noticed a couple of things:

The first thing is that your "Day Event 3 Times" event is not using the Europe/Berlin timezone for its dates, so the event is effectively in "floating time". This may not matter if your local timezone is Europe/Berlin tho.

Second, the same event spans 11 Sep - 12 Sep. So with the recurrence rule you will end up with three event instances:

  • 11 Sep - 12 Sep
  • 12 Sep - 13 Sep
  • 13 Sep - 14 Sep

I didn't look too closely at what the code is doing, but that might explain why you are getting matches on 14 sep.

fortuna
  • 701
  • 5
  • 7
  • Thanks for your Notices. I also took al look at the tests [link](http://code.google.com/p/ical4j/source/browse/test/net/fortuna/ical4j/filter/PeriodRuleTest.java?r=dd9e945f26dfa027ac520a3c6e311f35658ab9cd) There a one day event is created with a from and to date without a timezone. I experimente a little bit and found that is is working with a one time Event without recurring rule. If I add a reccuring roule even with COUNT=1 the entry now matches on two days, the start and the end date. – Michael Klenk Sep 25 '12 at 11:12