Не так давно у меня возникла необходимость парсинга и последующего вывода нужной информации из iCalendar. После упорных поисков я наткнулся на библиотеку iCal4J. Присмотревшись к её функционалу, я понял — это то, что мне нужно. Давайте же попробуем её применить на практике.
Подготовка календаря
В Google Calendar я создал маленький календарь, состоящий из нескольких различных мероприятий длительностью от 30 минут до 6 часов. Затем я скачал календарь в формате iCal к себе на ноутбук. Если кто не знает — делается это так: заходим в настройки календаря Google и в разделе «Закрытый адрес календаря» жмём на зеленую кнопочку «ICAL». Всё, календарь загружен на устройство.
Подготовка Java
Следующим этапом стала загрузка библиотеки и подключение ее к проекту. Распаковал и указал среде разработки папку с файлами библиотек *.jar. Также в папку с проектом был скопирован мой скачанный файл календаря. Все готово к написанию кода!
Загрузка календаря
Существует два варианта загрузки календаря — из файла и парсинг строки с содержимым календаря. Мы выберем первый способ (второй существенно не отличается от него).
Sample code
1
2
3
4
5
// Открываем входной поток из файла
FileInputStream fin = new FileInputStream("calendar.ics");
// И на основе этого потока парсим календарь в объект Calendar
CalendarBuilder builder = new CalendarBuilder();
Calendar calendar = builder.build(fin);
Вывод всех мероприятий
Давайте теперь попробуем вывести куда — нибудь (ну хотя бы в консоль) все мероприятия из нашего календаря.
Стоит обратить внимание на первую строчку, а именно Component.VEVENT. Так мы указываем, что хотим получить именно мероприятия календаря. Если не указать явно, что мы хотим извлечь из календаря, то мы получим список, в котором также окажутся To-Do компоненты (VTODO), заметки (VJOURNAL), и прочие компоненты типа VFREEBUSY, VALARM и VTIMEZONE.
Применение фильтров
Для того, чтобы вывести элементы, в моем случае мероприятия, в определенный период времени, можно применить фильтры.
Period period = new Period(new DateTime(today.getTime()), new Dur(1, 0, 0, 0));
// На его основе создаем фильтр
Filter filter = new Filter(new PeriodRule(period));
// Применяем фильтр к календарю
List eventsToday = filter.filter(calendar.getComponents(Component.VEVENT));
// Всё, в eventsToday хранятся все мероприятия, запланированные именно на сегодня
На момент написания в моем календаре хранились такие записи (в формате «Заголовок»: «Описание» [«Время начала»]):
Sample code
1
2
3
4
5
6
Event 1: Event 1 — November 1 [7 Nov 201313:00:00 GMT]
Event 5: Event 5 — November 12 [12 Nov 201312:00:00 GMT]
Event 3: Event 3 — November 10 [10 Nov 201319:30:00 GMT]
Event 2: Event 2 — November 9 [9 Nov 201308:30:00 GMT]
Event 4: Event 4 — November 11 [11 Nov 201308:00:00 GMT]
Event 6: Event 6 — November 13 [13 Nov 201309:30:00 GMT]
После применения фильтра на вывод запланированных мероприятий (на 11 ноября) я получил только одно мероприятие — Event 4: Event 4: Event 4 — November 11 [11 Nov 2013 08:00:00 GMT]
Увеличив период до трёх дней… Period period = new Period(new DateTime(today.getTime()), new Dur(3, 0, 0, 0));
… я получил такую картину:
Sample code
1
2
3
Event 5: Event 5 — November 12 [12 Nov 201312:00:00 GMT]
Event 4: Event 4 — November 11 [11 Nov 201308:00:00 GMT]
Event 6: Event 6 — November 13 [13 Nov 201309:30:00 GMT]
Создание пустого календаря
iCal4j поддерживает также создание календаря с нуля. Здесь всё просто. Создаем объект календаря, добавляем в него необходимые поля.
Поработав с календарем, нам конечно же нужно его сохранить. Лучше всего сохранить обратно в файл.
Sample code
1
2
3
FileOutputStream fout = new FileOutputStream("calendar.ics");
CalendarOutputter out = new CalendarOutputter();
out.output(calendar, fout);
Заключение
Мы рассмотрели базовые возможности библиотеки iCal4j. Конечно, её возможности не ограничиваются просто парсингом календаря и созданием событий. Библиотека позволяет также прикреплять файлы к событиям, создавать мероприятия с указанием места проведения в координатах, создавать списки приглашенных и многое другое. Помимо этого библиотека может использоваться в разработке Android приложений.