Wie kann in Java ein ical Termin (ics Datei) erzeugt werden?

Erstellt am 1. September 2019 von It_berater

Wer mit Java ical Termine erzeugen will, kann das gut mit der ical4j Lib machen. Es muss dazu in der pom.xml dieser Eintrag hinzugefügt werden.

<dependency>
	<groupId>org.mnode.ical4j</groupId>
	<artifactId>ical4j</artifactId>
	<version>3.0.4</version>
</dependency>

Dann wollen wir zuerst mal ein paar Zeilen für den JUnit Test dafür schreiben:

@Test
	void testWriteKalenderInDatei() throws Exception {

		Calendar icsCalendar = getTestkalenderMitEinTermin();

		String icsDateinamen = "JUnit-Testdatei.ics";
		Kalender.writeKalenderInDatei(icsCalendar, icsDateinamen);
	}

	private Calendar getTestkalenderMitEinTermin() {
		Calendar icsCalendar = Kalender.createKalender();
		TimeZone timezone = Kalender.createTimezoneEuropa();
		LocalDateTime eventStartZeitpunkt = LocalDateTime.now();
		String eventKommentar = "JUnit Test Kommentar";
		String eventTitel = "JUnit Event Titel";
		Kalender k = new Kalender();
		k.addTermin(icsCalendar, timezone, eventStartZeitpunkt, eventTitel, eventKommentar);
		return icsCalendar;
	}

Wir brauchen noch die Kalender Klasse, die hier kopiert werden kann:

import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.GregorianCalendar;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.TimeZone;
import net.fortuna.ical4j.model.TimeZoneRegistry;
import net.fortuna.ical4j.model.TimeZoneRegistryFactory;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.component.VTimeZone;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.Description;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.RandomUidGenerator;
import net.fortuna.ical4j.util.UidGenerator;

/**
 * Ein ics Kalender.
 * 
 * @author Thomas Wenzlaff
 *
 */
public class Kalender {

	private static final Logger LOG = LogManager.getLogger(Kalender.class);

	private static final String PRODUKT_ID = "-//Thomas Wenzlaff//www.wenzlaff.de 1.0//DE";

	private static final int TERMIN_DAUER_IN_MINUTEN = 15;

	private UidGenerator uidGenerator;

	/**
	 * Konstruktor.
	 */
	public Kalender() {
		LOG.debug("Konstruktor");
		uidGenerator = new RandomUidGenerator(); // wir nutzen den Zufallsgenerator, möglich währe auch der FixedUidGenerator
	}

	/**
	 * Fügt einen Termin von 15 Minuten Dauer hinzu.
	 * 
	 * @param icsCalendar         der Kalender
	 * @param timezone            die Zeitzone
	 * @param eventStartZeitpunkt der Zeitpunkt wo der Termin startet
	 * @param eventTitel          der Titel des Termins
	 * @param eventKommentar      der Kommentar des Termin
	 */
	public void addTermin(Calendar icsCalendar, TimeZone timezone, LocalDateTime eventStartZeitpunkt, String eventTitel, String eventKommentar) {

		java.util.Calendar startDate = getZeitpunkt(eventStartZeitpunkt, timezone);

		java.util.Calendar endDate = getZeitpunkt(eventStartZeitpunkt.plusMinutes(TERMIN_DAUER_IN_MINUTEN), timezone);

		VEvent bibelleseTermin = erzeugeEvent(startDate, endDate, eventTitel, eventKommentar);

		VTimeZone tz = timezone.getVTimeZone();
		bibelleseTermin.getProperties().add(tz.getTimeZoneId());

		setUid(bibelleseTermin);

		icsCalendar.getComponents().add(bibelleseTermin);
	}

	/**
	 * Erzeugt einen Gregorianischen Kalender.
	 * 
	 * @return Kalender
	 */
	public static Calendar createKalender() {

		Calendar icsCalendar = new Calendar();
		icsCalendar.getProperties().add(new ProdId(PRODUKT_ID));
		icsCalendar.getProperties().add(Version.VERSION_2_0);
		icsCalendar.getProperties().add(CalScale.GREGORIAN);

		LOG.info("Kalender erzeugt mit ProduktId: " + icsCalendar.getProductId());
		return icsCalendar;
	}

	/**
	 * Erzeugt eine Zeitzone für Europa.
	 * 
	 * Wir brauchen das Propertie:
	 * net.fortuna.ical4j.timezone.cache.impl=net.fortuna.ical4j.util.MapTimeZoneCache
	 * in der ical4j.properties
	 * 
	 * @return Zeitzone für Europa.
	 */
	public static TimeZone createTimezoneEuropa() {

		TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
		TimeZone timezone = registry.getTimeZone("Europe/Berlin");
		LOG.info("Timezone erzeugt: " + timezone.getDisplayName());
		return timezone;
	}

	public static void writeKalenderInDatei(Calendar icsCalendar, String icsDateinamen) throws IOException {

		LOG.debug("Schreibe icsCalendar in Datei: " + icsDateinamen);

		FileOutputStream fout = new FileOutputStream(icsDateinamen);

		CalendarOutputter outputter = new CalendarOutputter();
		outputter.output(icsCalendar, fout);
	}

	private static VEvent erzeugeEvent(java.util.Calendar startDate, java.util.Calendar endDate, String eventTitel, String eventKommentar) {

		DateTime start = new DateTime(startDate.getTime());
		DateTime end = new DateTime(endDate.getTime());
		VEvent bibelleseTermin = new VEvent(start, end, eventTitel);
		bibelleseTermin.getProperties().add(new Description(eventKommentar));

		LOG.debug("Erzeugter Start-Event: " + start + ", Event Titel: " + eventTitel + ", Kommentar: " + eventKommentar);

		return bibelleseTermin;
	}

	private static java.util.Calendar getZeitpunkt(LocalDateTime eventZeitpunkt, TimeZone timezone) {

		java.util.Calendar startDate = new GregorianCalendar();
		startDate.setTimeZone(timezone);
		startDate.set(java.util.Calendar.MONTH, eventZeitpunkt.getMonthValue() - 1);
		startDate.set(java.util.Calendar.DAY_OF_MONTH, eventZeitpunkt.getDayOfMonth());
		startDate.set(java.util.Calendar.YEAR, eventZeitpunkt.getYear());
		startDate.set(java.util.Calendar.HOUR_OF_DAY, eventZeitpunkt.getHour());
		startDate.set(java.util.Calendar.MINUTE, eventZeitpunkt.getMinute());
		startDate.set(java.util.Calendar.SECOND, eventZeitpunkt.getSecond());
		return startDate;
	}

	private void setUid(VEvent termin) {

		Uid uid = uidGenerator.generateUid();
		termin.getProperties().add(uid);
	}

}

Damit der Test auch durchläuft, brauche wir auch noch eine ical4j.properties Datei mit folgenden Inhalt im /src/man/resources Verzeichnis, sonst klappt es nicht mit der Zeitzone:

ical4j.unfolding.relaxed=true
ical4j.compatibility.outlook=true
ical4j.compatibility.notes=true
ical4j.parsing.relaxed=true
ical4j.validation.relaxed=true
net.fortuna.ical4j.timezone.cache.impl=net.fortuna.ical4j.util.MapTimeZoneCache

Wenn der Test erfolgreich durchgelaufen ist:

finden wir die isc-Datei mit dem Termin, der in jeden Kalender importiert werden kann:

BEGIN:VCALENDAR
PRODID:-//Thomas Wenzlaff//www.wenzlaff.de 1.0//DE
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20190901T172105Z
DTSTART:20190901T192104
DTEND:20190901T193604
SUMMARY:JUnit Event Titel
DESCRIPTION:JUnit Test Kommentar
TZID:Europe/Berlin
UID:4cbf53d2-83e3-488d-b1c5-6e62e2335b56
END:VEVENT
END:VCALENDAR

Ähnliche Artikel:

  1. Wie kann mit der neuen Java Zeit API 1.8 ein Zeitstempel (2014-01-31_15:12:00) erzeugt werden?
  2. Wie kann mit Java 8 und dem DOM-Parser einfach eine XML Datei erzeugt werden?
  3. Java Rätsel des Monats