PHP: Bei Datum im ISO 8601 Format einen Tag draufrechnen

Saugkraft

Saugkraft

Aktives Mitglied
Thread Starter
Dabei seit
20.02.2005
Beiträge
9.022
Reaktionspunkte
3.189
Hallöchen ihr Nerds.

Ich möchte bei einem ISO 8601 formatierten Datum (20171103T000000Z) einen Tag draufrechnen, um auf 20171104T000000Z zu kommen.

Der Grund: Ich hole mir Termine aus einer Datenbank, gebe die im ISO 8601 Format aus und schreibe sie in eine vCalendar Datei. Um einen ganztätigen Termin zu erzeugen, müssen Beginn und Ende einen Tag Differenz haben.

Ich hab es mit explode.. probiert, um mir den Datumsteil rauszuziehen (20171103), damit ich den in Integer (int)20171103 wandeln, 1 addieren (+1) und zurück in String wandeln kann. Klappt leider nicht, weil das Ergebnis aus (int)20170311 immer leer ist.

Hat jemand eine Idee?
 
Konvertier doch einfach mittels strtotime() nach Unix, rechne 86400 drauf und dann mit date_format() wieder nach 8601 zurück.

PHP:
$iso8601_old = '20171103T000000Z';
echo $iso8601_old.'<br />';

$unixstamp_old = strtotime($iso8601_old);
echo $unixstamp_old.'<br />';

$unixstamp_new = $unixstamp_old + 86400;
echo $unixstamp_new.'<br />';

$ios8601_new = date_format(date_create('@'. $unixstamp_new), 'Ymd\THis\Z');
echo $ios8601_new;
ergibt:
PHP:
20171103T000000Z
1509667200
1509753600
20171104T000000Z
 
So hätte ich es auch gemacht, ggf. über ein DateTime Objekt.
 
Danke Leute. Das klappt. :thumbsup:

iCal ist eine elende Zicke. Was ich mir da schon einen Wolf programmiert hab. :rolleyes:
 
Kleine Frage knapp am Thema vorbei: Welche vCalendar Version /Spezifikation nimmst du denn? Ich hab es noch nie geschafft, Outlook, Windows Mail/Kalender, OSX/iOS Kalender und Thunderbirds/Lightning und Sogo gemeinsam glücklich zu machen. (Wobei Lightning insgesamt wirklich sehr enttäuschend ist).
 
Version 2.

Hier mal meine nackte iCal Datei:
Code:
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
VERSION:2.0
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
END:VCALENDAR

Ich jage die erstellen Dateien immer gerne durch den Syntax Checker von Steven Severinghaus: http://severinghaus.org/projects/icv/
Der zeigt dir zwar diverse Fehler nicht an, ist aber zumindest für das grobe sehr gut.

Es gibt ein paar Ecken, über die du leicht stolpern kannst. Ist aber fallabhängig. Eventuell kann ich da helfen. So ein elender Miststückfehler ist z.B. wenn du bei der UID schlampst. iCal weigert sich, ganztägige Termine einzutragen wenn er zwei gleiche UIDs findet. Die in dem Beispiel hab ich mit einer eindeutigen ID versehen (4242, kommt aus der Datenbank) und setze das Datum des Termins hinten dran.

Code:
BEGIN:VEVENT
CLASS:PUBLIC
TZID=Europe/Berlin
CREATED:20171111T210042Z
DESCRIPTION:Treffen mit wichtigen Typen
DTSTAMP:20171111T210042Z
DTSTART;TZID=Europe/Berlin:20170109T180000
DTEND;TZID=Europe/Berlin:20170109T200000
LAST-MODIFIED:20171111T210042Z
LOCATION:Hinterhaus
URL:https://www.example.com
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=de:Treffen mit wichtigen Typen
TRANSP:OPAQUE
UID:424220170109T180000
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-ALLOWEXTERNCHECK:TRUE
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-CONFTYPE:0
BEGIN:VALARM
TRIGGER:-PT1440M
ACTION:DISPLAY
DESCRIPTION:Reminder - Reminder Text Goes Here
END:VALARM
END:VEVENT

Andere Geschichten sind z.B. DTSTAMP und LAST-MODIFIED. Die müssen immer in UTC angegeben und mit Z gekennzeichnet sein.

Die gröberen Fehler, die ich früher gemacht hab, ist der falsche Umgang mit der Zeitzone. Da kursieren so einige Anleitungen im Netz, die nicht stimmen. Wenn es Probleme mit der Zeitzone gibt, dann merkst du das ziemlich leicht an Terminverschiebungen innerhalb/außerhalb der Sommerzeit. Je nachdem wann du die Datei erstellt hast, wird dann pauschal eine Stunde draufgeschlagen oder eben nicht.

Mangels SoGo kann ich's nicht testen, aber mein Code sollte (hoffentlich) in allen Systemen funktionieren.
 
  • Gefällt mir
Reaktionen: wegus, ruerueka und chris25
@Saugkraft: Vielen Dank für das ausführliche Beispiel und die Hinweise. Den Syntaxchecker kannte ich noch nicht, werde ich ausprobieren.
Das Zeitzonenthema bzw. die falsche Doku im Netz war mir so nicht klar, da werde ich künftig drauf achten.
Wenn ich dem Beispiel einen einrahmenden BEGIN:VCALENDAR / END:VCALENDAR spendiere, kann es in Thunderbird/Lightning korrekt importiert werden und wird auch von SOGo in der Mail-Darstellung erkannt, allerdings mit 1 Stunde Verschiebung (d.h. es wird 19 bis 21 Uhr angezeigt). Ich hätte vom Cod her 19 bis 20 Uhr erwartet. Übersehe ich wieder ein wichtiges Kennzeichen? Oder ist SOGo hier auch einfach nur rudimentär implementiert (ist eh leider nicht wirklich mit Exchange zu vergleichen...)?
Ich sehe schon, da muss ich noch Zeit reinhängen. Mein erster Ansatz wäre, immer alle Termine in UTC umzurechnen und entsprechend mit 'Z' zu notieren, dann hab ich wenigstens ene Gleichbehandlung....
 
Hast du es mal so (beides zusammen komplett) probiert?

Code:
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
VERSION:2.0
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
TZID=Europe/Berlin
CREATED:20171111T210042Z
DESCRIPTION:Sommerzeit
DTSTAMP:20171111T210042Z
DTSTART;TZID=Europe/Berlin:20180515T180000
DTEND;TZID=Europe/Berlin:20180515T200000
LAST-MODIFIED:20171111T210042Z
LOCATION:virtuell
URL:https://www.example.com
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=de:Sommerzeit
TRANSP:OPAQUE
UID:424220180511T180000
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-ALLOWEXTERNCHECK:TRUE
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-CONFTYPE:0
END:VEVENT
BEGIN:VEVENT
CLASS:PUBLIC
TZID=Europe/Berlin
CREATED:20171111T210042Z
DESCRIPTION:Winterzeit
DTSTAMP:20171111T210042Z
DTSTART;TZID=Europe/Berlin:20171115T180000
DTEND;TZID=Europe/Berlin:20171115T200000
LAST-MODIFIED:20171111T210042Z
LOCATION:virtuell
URL:https://www.example.com
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=de:Winterzeit
TRANSP:OPAQUE
UID:424220170109T180000
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-ALLOWEXTERNCHECK:TRUE
X-MS-OLK-AUTOFILLLOCATION:FALSE
X-MS-OLK-CONFTYPE:0
END:VEVENT
END:VCALENDAR

Die Stunde Verschiebung deutet daraufhin, dass Sogo die Zeitzone nicht (korrekt) interpretiert.

Ich hab den ersten Event mal auf morgen (15.11.) gelegt und Winterzeit genannt. Der zweite ist am 15.05.2018 und heißt Sommerzeit. Beide gehen von 18-20 Uhr.

Probier mal damit. Wenn einer von beiden 18-20 und der andere mit 19-21 Uhr oder mit 17-19 Uhr eingetragen wird, ist es ein Zeitzonen- bzw. Sommer-/Winterzeit-Problem.
 
  • Gefällt mir
Reaktionen: ruerueka
Vielen Dank!
Hier meine Testergebnisse:
Thunderbird/Lightning macht es wieder richtig, SOGo erkennt den Termin gar nicht mehr, es mag wohl nicht mehr als einen Eintrag...
Mit dem iPhone klappt es auch auf Anhieb richtig.

Mein Fazit:
- Thunderbird/Lightning ist unpraktisch, kann aber zumindest korrekt definierte ics Dateien importieren (mit Plugin und nur mit dem Umweg über den Desktop)
- SOGo kann nur "einfache" Termine in der Mail-Ansicht darstellen, aber auch aus einem einfachen Termin keinen korrekten Kalendereintrag daraus machen. Evtl. ist das auch nur ein Konfigurationsproblem, unsere IT behauptet aber: nö, das gehört so, sie haben nichts ausgeschaltet...
- iOS Mail / iOS Calendar ist der komfortabelste Weg, um empfangene ics Dateien mit einem "Fingertip" in einen Kalender einzutragen
- für die Generierung eigener Termine hab ich jetzt eine komfortable Vorlage und nützliche Hinweise - herzlichen Dank!
 
Zurück
Oben Unten