iCal icon indicating copy to clipboard operation
iCal copied to clipboard

Timezone offset used as TZID

Open bicpi opened this issue 3 years ago • 2 comments

Hi, when using ...

$event = (new Event())
    ->setSummary('Your appointment')
    ->setOccurrence(
        new TimeSpan(
            new DateTime(new \DateTimeImmutable('2022-05-11T14:00:00+00:00'), true),
            new DateTime(new \DateTimeImmutable('2022-05-11T14:00:00+00:00'), true)
        ));
$calendar = new Calendar([$event]);
$calendarComponent = (new CalendarFactory())->createCalendar($calendar);
echo (string) $calendarComponent;

... I get ...

BEGIN:VCALENDAR
PRODID:-//eluceo/ical//2.0/EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
UID:74415f56413f134e3b7ff105fec747d8
DTSTAMP:20210430T120042Z
SUMMARY:Your appointment
DTSTART;TZID=+00:00:20220511T140000
DTEND;TZID=+00:00:20220511T140000
END:VEVENT
END:VCALENDAR

This is not supported by e.g. the Calendar app on the Mac. It seems the problem is using the timezone offset +00:00 for the TZID; when changing it to UTC, it works.

Philipp

bicpi avatar Apr 30 '21 12:04 bicpi

I realized, that this error occurs when no timezone is specified in the DateTime PHP object but still $applyTimeZone is set in the constructor for the iCal DateTime object.

It would work if the above code were changed to this:

$event = (new Event())
    ->setSummary('Your appointment')
    ->setOccurrence(
        new TimeSpan(
            new DateTime(new \DateTimeImmutable('2022-05-11T14:00:00+00:00',new DateTimeZone('Europe/London')), true),
            new DateTime(new \DateTimeImmutable('2022-05-11T14:00:00+00:00',new DateTimeZone('Europe/London')), true)
        ));
$calendar = new Calendar([$event]);
$calendarComponent = (new CalendarFactory())->createCalendar($calendar);
echo (string) $calendarComponent;

hansmorb avatar Apr 22 '22 12:04 hansmorb

I tried with an upgrade to v2.7.0; the .ics file still cannot be imported into a Mac's calendar because of the TZ setting:

use Eluceo\iCal\Domain\Entity\Calendar;
use Eluceo\iCal\Domain\Entity\Event;
use Eluceo\iCal\Domain\ValueObject\DateTime;
use Eluceo\iCal\Domain\ValueObject\TimeSpan;
use Eluceo\iCal\Presentation\Factory\CalendarFactory;

$event = (new Event())
    ->setSummary('Your appointment')
    ->setOccurrence(
        new TimeSpan(
            new DateTime(new \DateTimeImmutable('2022-09-18T15:00:00+00:00'), true),
            new DateTime(new \DateTimeImmutable('2022-09-18T15:30:00+00:00'), true)
        )
    );
$calendar = new Calendar([$event]);
$componentFactory = new CalendarFactory();
$calendarComponent = $componentFactory->createCalendar($calendar);

file_put_contents(__DIR__.'/test.ics', (string) $calendarComponent);

Output:

BEGIN:VCALENDAR
PRODID:-//eluceo/ical//2.0/EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
UID:c36aa9c9566024f3b4b1a2915160cb70
DTSTAMP:20220904T074326Z
SUMMARY:Your appointment
DTSTART;TZID=+00:00:20220918T150000
DTEND;TZID=+00:00:20220918T153000
END:VEVENT
END:VCALENDAR

Changing the TZID manually to TZID=UTC makes it work:

DTSTART;TZID=UTC:20220918T150000
DTEND;TZID=UTC:20220918T153000

bicpi avatar Sep 04 '22 07:09 bicpi

Hi, thanks for the update; I tried the described use case with the latest v2.10 but still seeing the issue.

Note that the timezone is not given explicitly through the $timezone parameter of new \DateTimeImmutable($datetime, $timezone) but implicitly in the $datetime string as described in the PHP docs for the timezone param: The $timezone parameter and the current timezone are ignored when the $datetime parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone

$dt = new \DateTimeImmutable('2022-05-11T14:00:00+08:00');
echo $dt->getTimezone()->getName(); // => 08:00

bicpi avatar Jan 17 '23 21:01 bicpi