Hintergrund

Siehe den Blogeintrag zu Idee und Hintergrund dieses Notebooks

Package icalenar wird benötigt, um ics Files zu erzeugen.

In [1]:
import icalendar
import datetime
import os

anzahl_wochen gibt an, für wieviele Wochen es Kalendereinträge geben soll, z.B.: Lukas: 25 W. Analog für anzahl_monate und anzahl_jahre.

In [2]:
anzahl_wochen = 25
anzahl_monate = 24
anzahl_jahre = 99

Zusätzlich kann man noch besondere Tage angeben, an denen Julia z.B. 1000 Tage alt ist.

In [3]:
# Tausend Tage sind grob 3 Jahre, somit 30000 Tage rund 90 Jahre
besondere_tage = (100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000)
besondere_tage = besondere_tage + (3333, 11111, 22222, 33333)

Hier werden die Personen und ihre Geburtstage eingegeben.

In [4]:
geburtstage = {'Lukas': datetime.date(2016,3,3), 
               'Julia': datetime.date(2015,12,12)}

Nun wird ein Dictionary erzeugt, das für jede Person die Einträge mit den entsprechenden Tagen enthält.

In [5]:
# Dictionary für Kalendereinträge
eintraege = dict()

for name in geburtstage:
    geburtstag = geburtstage[name]

    # Geburtstag
    eintraege['{name}: Geburtstag'.format(name=name, geburtstag=geburtstag)] = geburtstag

    # Ersten Wochen
    for nr_wochen in range(1,anzahl_wochen+1):
        text = '{name}: {nr_wochen:02d} W'.format(name=name, nr_wochen=nr_wochen)
        eintraege[text] = geburtstag + datetime.timedelta(weeks=nr_wochen)

    # Ersten Monate
    for nr_monate in range(1,anzahl_monate+1):
        text = '{name}: {nr_monate:02d} M'.format(name=name, nr_monate=nr_monate)
        monat = (geburtstag.month -1 + nr_monate) % 12 + 1
        jahr  = geburtstag.year + ((( geburtstag.month - 1) + nr_monate ) // 12 )
        # Für 12 Monate, 24 Monate, ... soll kein Eintrag erstellt werden
        if monat != geburtstag.month:
            eintraege[text] = datetime.date(jahr, monat, geburtstag.day)

    # Geburtstage        
    for nr_jahre in range(1,anzahl_jahre+1):
        text = '{name}: {nr_jahre:02d} J'.format(name=name, nr_jahre=nr_jahre)
        eintraege[text] = datetime.date(geburtstag.year + nr_jahre, geburtstag.month, geburtstag.day)

    # besondere Tage
    for tage in besondere_tage:
        text = '{name}: {tage} Tage'.format(name=name, tage=tage)
        eintraege[text] = geburtstag + datetime.timedelta(days = tage)

eintraege enthält nun z.B.:

In [6]:
eintraege['Lukas: Geburtstag']
Out[6]:
datetime.date(2016, 3, 3)
In [7]:
eintraege['Julia: 100 Tage']
Out[7]:
datetime.date(2016, 3, 21)

Einträge, die in der Vergangenheit liegen, werden nun herausgefiltert. Sprich es werden nur zukünftige Einträge in das Kalenderfile geschrieben. Falls man doch auch vergangene Einträge im Kalender haben will, diese Zelle einfach nicht ausführen.

In [8]:
print('Anzahl Einträge insgesamt: ', len(eintraege))

eintraege = {text: eintraege[text] for text in eintraege if eintraege[text] > datetime.date.today()}

print('Anzahl Einträge in der Zukunft: ', len(eintraege))
Anzahl Einträge insgesamt:  320
Anzahl Einträge in der Zukunft:  281

Nun wird das Kalenderfile mit Hilfe von icalendar erzeugt, ...

In [10]:
cal = icalendar.Calendar()
cal.add('prodid', 'Geburtstags-Kalender')
cal.add('version', '2.0')

for text in eintraege:
#    print(text, '---', eintraege[text])
    event = icalendar.Event()
    event.add('summary', text)
    event.add('dtstart', eintraege[text])
    event.add('dtend', eintraege[text])
    cal.add_component(event)    

... gespeichert ...

In [11]:
f = open('Kalender.ics', 'wb')
f.write(cal.to_ical())
f.close()

... und ein Download-Link erzeugt:

In [12]:
from IPython.display import FileLink
FileLink('Kalender.ics')
Out[12]:
In [ ]: