Menu

Recurrence / Google ICAL File

2014-11-21
2014-11-22
  • Philipp Walther

    Philipp Walther - 2014-11-21

    hi all

    I'm trying to parse a simple iCal file exported from Google Calendar using this library.

    It's 1 Event that has 35 recurrences - I'd expect getRecurrenceDates() to return those dates. Currently I get an empty list.

    Do I misunderstand the API or is this work in progress, a malformed file maybe?

    BEGIN:VCALENDAR
    PRODID:-//Google Inc//Google Calendar 70.9054//EN
    VERSION:2.0
    CALSCALE:GREGORIAN
    METHOD:PUBLISH
    X-WR-CALNAME:openHab
    X-WR-TIMEZONE:Europe/Zurich
    X-WR-CALDESC:openHab cal
    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
    BEGIN:VEVENT
    DTSTART;TZID=Europe/Zurich:20141121T223000
    DTEND;TZID=Europe/Zurich:20141121T233000
    RRULE:FREQ=WEEKLY;COUNT=35;BYDAY=FR
    DTSTAMP:20141121T210407Z
    UID:ijfvd5k25ire72b57mcbpqo1b8@google.com
    CREATED:20141121T202934Z
    DESCRIPTION:start {\n update Window OPEN\n} \nend {\n update Window CLOSED\
     n}
    LAST-MODIFIED:20141121T210359Z
    LOCATION:Zurich\, Switzerland
    SEQUENCE:2
    STATUS:CONFIRMED
    SUMMARY:open hab event
    TRANSP:OPAQUE
    END:VEVENT
    END:VCALENDAR
    

    My code:

        File f = new File("repeat_2times.txt");
        List<ICalendar> ical = Biweekly.parse(f).all();
        for (ICalendar iCalItem : ical) {
            List<VEvent> events = iCalItem.getEvents();
            for (VEvent evt : events) {
                List<RecurrenceDates> l = evt.getRecurrenceDates();
                LOG.info(l.size() + " list recurrence items");
            }
        }
    

    ~~~~~~~~

     
  • Philipp Walther

    Philipp Walther - 2014-11-22

    Oh I see now - It seems to need RDATE for that, it doesn't 'solve' RRULE for me. Although I can see there's some (Google) source in there for that..?

     
  • Philipp Walther

    Philipp Walther - 2014-11-22

    So I've tried to use the RecurrenceRule to google.RRule conversion, but I seem to lose the TimeZone information (on master). Bug in StreamReader? (0.3.3 doesn't have ByDay and other classes, so I cannot use that)

     

    Last edit: Philipp Walther 2014-11-22
  • Philipp Walther

    Philipp Walther - 2014-11-22

    Ok, so if anyone is interested, I fixed it this way:

    io.StreamReader:

       //remove the VTIMEZONE components from the iCalendar object
        if (toKeep.isEmpty() && vcalComponent != null) {
            ical.removeComponents(VTimezone.class);
        } else if(!toKeep.isEmpty()) {
            //keep the VTIMEZONE components that don't have IDs
            ical.getComponents().replace(VTimezone.class, toKeep);
        }
    

    and then use the google code to convert:

                    RecurrenceRule rule = evt.getRecurrenceRule();
                    RRule grule = ICalTimeZone.convert(rule);
                    VTimezone tz =     iCalItem.getComponent(VTimezone.class);
    
                    TimeZone tzone =     TimeZone.getTimeZone(tz.getTimezoneId().getValue());
    
                    DateValue dvstart =     ICalTimeZone.convert(evt.getDateStart());
                    RecurrenceIterator iter =     RecurrenceIteratorFactory.createRecurrenceIterator(grule, dvstart, tzone);
                    while(iter.hasNext()) {
                        System.out.println(iter.next());
                    }
    

    I made my own copy of IcalTimeZone and changed the convert(..) methods to public so I can access them.

    I'm still not sure why 0.3.4 removes/hides the TimeZone information.

     
  • Michael Angstadt

    Hi Philip,

    The whole idea behind removing the VTIMEZONE components from the "ICalendar" object is that they are not part of the iCalendar "data-model" per se. They are only needed to let the parser know how to parse each date property value. After the values are parsed in their appropriate timezones, the VTIMEZONEs are not needed. However, you can still access them through the "ICalReader.getTimezoneInfo()" method if you wish.

    This is part of the major timezone-related changes I've added to this version, so please let me know if you see anything wrong with this!

    I just added a "getDateIterator()" method to the "RecurrenceRule" class, so you don't have to go through all that trouble.

    :::java
    RecurrenceRule rule = evt.getRecurrenceRule();
    DateIterator it = rule.getDateIterator();
    while(it.hasNext()){
      System.out.println(it.next());
    }
    

    I will be releasing a new stable version soon, so stay tuned! :D

     

Anonymous
Anonymous

Add attachments
Cancel





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.