Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Java и работа с iCalendar

Anna | 3.06.2014 | нет комментариев
Не так давным-давно у меня появилась надобность парсинга и дальнейшего итога требуемой информации изiCalendar. Позже упорных поисков я наткнулся на библиотеку iCal4J. Присмотревшись к её функционалу, я осознал — это то, что мне необходимо. Давайте же испробуем её применить на практике.

Подготовка календаря

В Google Calendar я сотворил небольшой календарь, состоящий из нескольких разных мероприятий продолжительностью от 30 минут до 6 часов. После этого я скачал календарь в формате iCal к себе на ноутбук. Если кто не знает — делается это так: заходим в настройки календаря Google и в разделе «Закрытый адрес календаря» жмём на зеленую кнопочку «ICAL». Всё, календарь загружен на устройство.

Подготовка Java

Дальнейшим этапом стала загрузка библиотеки и подключение ее к плану. Распаковал и указал среде разработки папку с файлами библиотек *.jar. Также в папку с планом был скопирован мой скачанный файл календаря. Все готово к написанию кода!

Загрузка календаря

Существует два варианта загрузки календаря — из файла и парсинг строки с содержимым календаря. Мы предпочтем 1-й метод (2-й значительно не отличается от него).

// Открываем входной поток из файла
FileInputStream fin = new FileInputStream("calendar.ics");
// И на основе этого потока парсим календарь в объект Calendar
CalendarBuilder builder = new CalendarBuilder();
Calendar calendar = builder.build(fin);
Итог всех мероприятий

Давайте сейчас испробуем вывести куда — нибудь (ну правда бы в консоль) все мероприятия из нашего календаря.

// Получаем список мероприятий
ComponentList listEvent = calendar.getComponents(Component.VEVENT);
for (Object elem : listEvent) {
	// Нам придется очевидно привести элемент списка к надобному типу, так как listEvent хранит элементы Object
	VEvent event = (VEvent) elem;
	// Получаем изложение
	// getValue() делаем для того, Дабы извлечь только значение. Доступные способы getName() и toString() вернут в себе еще значение тега DESCRIPTION
	String description = event.getDescription().getValue();
	// Получаем заголовок мероприятия 
	String title = event.getSummary().getValue();
	System.out.println(title   " : "   description);
}

Стоит обратить внимание на первую строчку, а именно Component.VEVENT. Так мы указываем, что хотим получить именно мероприятия календаря. Если не указать очевидно, что мы хотим извлечь из календаря, то мы получим список, в котором также окажутся To-Do компоненты (VTODO), заметки (VJOURNAL), и прочие компоненты типа VFREEBUSY, VALARM и VTIMEZONE.

Использование фильтров

Для того, Дабы вывести элементы, в моем случае мероприятия, в определенный период времени, дозволено применить фильтры.

java.util.Calendar today = java.util.Calendar.getInstance();
today.set(java.util.Calendar.HOUR_OF_DAY, 0);
today.clear(java.util.Calendar.MINUTE);
today.clear(java.util.Calendar.SECOND);
// Создаем период времени в 1 день
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 хранятся все мероприятия, намеченные именно на сегодня

На момент написания в моем календаре хранились такие записи (в формате «Заголовок»: «Изложение» [«Время начала»]):

Event 1: Event 1 — November 1 [7 Nov 2013 13:00:00 GMT]
Event 5: Event 5 — November 12 [12 Nov 2013 12:00:00 GMT]
Event 3: Event 3 — November 10 [10 Nov 2013 19:30:00 GMT]
Event 2: Event 2 — November 9 [9 Nov 2013 08:30:00 GMT]
Event 4: Event 4 — November 11 [11 Nov 2013 08:00:00 GMT]
Event 6: Event 6 — November 13 [13 Nov 2013 09: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));

… я получил такую картину:

Event 5: Event 5 — November 12 [12 Nov 2013 12:00:00 GMT]
Event 4: Event 4 — November 11 [11 Nov 2013 08:00:00 GMT]
Event 6: Event 6 — November 13 [13 Nov 2013 09:30:00 GMT]

Создание пустого календаря

iCal4j поддерживает также создание календаря с нуля. Тут всё легко. Создаем объект календаря, добавляем в него нужные поля.

Calendar calendar = new Calendar();
calendar.getProperties().add(new ProdId("-//habrahabr"));
calendar.getProperties().add(Version.VERSION_2_0);
calendar.getProperties().add(CalScale.GREGORIAN);
Добавление нового мероприятия в календарь

Вот с созданием мероприятия все не так легко, но если разобраться, то все пойдет довольно стремительно.

// Устанавливаем часовой пояс
TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
TimeZone timezone = registry.getTimeZone("Europe/Minsk");
VTimeZone tz = timezone.getVTimeZone();
 // Предисловие 10 ноября в 18:00
java.util.Calendar startDate = new GregorianCalendar();
startDate.setTimeZone(timezone);
startDate.set(java.util.Calendar.MONTH, java.util.Calendar.NOVEMBER);
startDate.set(java.util.Calendar.DAY_OF_MONTH, 10);
startDate.set(java.util.Calendar.YEAR, 2013);
startDate.set(java.util.Calendar.HOUR_OF_DAY, 18);
startDate.set(java.util.Calendar.MINUTE, 0);
startDate.set(java.util.Calendar.SECOND, 0);
 // Конец в данный же день в 20:00
java.util.Calendar endDate = new GregorianCalendar();
endDate.setTimeZone(timezone);
endDate.set(java.util.Calendar.MONTH, java.util.Calendar.NOVEMBER);
endDate.set(java.util.Calendar.DAY_OF_MONTH, 10);
endDate.set(java.util.Calendar.YEAR, 2013);
endDate.set(java.util.Calendar.HOUR_OF_DAY, 20);
endDate.set(java.util.Calendar.MINUTE, 0);	
endDate.set(java.util.Calendar.SECOND, 0);
// Создаем событие
String eventName = "Какое-то мероприятие";
DateTime start = new DateTime(startDate.getTime());
DateTime end = new DateTime(endDate.getTime());
VEvent meeting = new VEvent(start, end, eventName);
// Добавляем к нему информацию о часовом поясе
meeting.getProperties().add(tz.getTimeZoneId());
// Создаем сам календарь
Calendar icsCalendar = new Calendar();
icsCalendar.getProperties().add(new ProdId("-//habrahabr"));
icsCalendar.getProperties().add(CalScale.GREGORIAN);
// Добавляем к нему сделанное событие
icsCalendar.getComponents().add(meeting);
Сохранение календаря в файл

Поработав с календарем, нам безусловно же необходимо его сберечь. Отменнее каждого сберечь обратно в файл.

FileOutputStream fout = new FileOutputStream("calendar.ics");
CalendarOutputter out = new CalendarOutputter();
out.output(calendar, fout);
Завершение

Мы разглядели базовые вероятности библиотеки iCal4j. Безусловно, её вероятности не ограничиваются легко парсингом календаря и созданием событий. Библиотека разрешает также прикреплять файлы к событиям, создавать мероприятия с указанием места проведения в координатах, создавать списки приглашенных и многое другое. Помимо этого библиотека может применяться в разработке Android приложений.

Ссылки:

  1. Изложение iCalendar
  2. Документация по iCal4j
  3. iCal4j Wiki (тут же дозволено и загрузить библиотеку)

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB