Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues 197 & 208 #228

Merged
merged 1 commit into from
Jul 17, 2019
Merged

Fix issues 197 & 208 #228

merged 1 commit into from
Jul 17, 2019

Conversation

s0600204
Copy link
Collaborator

@s0600204 s0600204 commented Jul 15, 2019

This changeset should resolve both issues #197 and #208 (which are the same problem).

I have not added a test to composer test, as the files there are hard-coded to examine the contents of DTSTART_array, and modifying the test scripts to be able to test any (other) parameter is beyond the scope of this PR.

Instead, running the ICS fragments posted with the issues in question should be enough, with the following notes:

Issue #197:

  • The expected value of DTSTART_tz should be "20181204T180000".
  • Setting $defaultTimezone has no effect on this, as the ics-parser assumes that that the single VTIMEZONE given in the ics fragment is the calendar's time zone.
  • If you change the VTIMEZONE statement (or remove it) so that the parser determines the calendar's time zone is "Europe/Copenhagen", then the expected value if DTSTART_tz would be "20181205T000000".

Issue #208:

  • The second event in the provided ics fragment contains an RRULE that repeats daily for over a year and a half.
  • Removing said event (so we don't have to check 500+ entries), the DTSTART_tz of the remaining events should be: '20190322T144500', '20190313T093000', '20190314T133000', '20190314T140000', '20190313T113000', '20190313T153000', '20190313T100000' in that order.
  • (There is also an event later on that has RDATEs set, but we don't support those yet.)

The last chunk in this patch isn't necessary to this fix, but is related cleanup.

`DateTime->setTimezone` does not modify the underlying value of a DateTime.

It changes how values passed to `DateTime->setDate`, `DateTime->setISODate`,
and `DateTime->setTime` should be interpreted; and also what timezone to
export a date in when using `DateTime->format`.
@u01jmg3
Copy link
Owner

u01jmg3 commented Jul 15, 2019

Thanks for this.

  • I am seeing differences in the output of examples/ICal.ics for DTSTART_TZ / DTEND_TZ mainly in the Microsoft Unicode CLDR EXDATE Test event
    • Can you double check this is correct with your new code?

I have not added a test to composer test, as the files there are hard-coded

@s0600204
Copy link
Collaborator Author

Okay (lengthy post, sorry):

Adding the following code to the top of example/index.php, between lines 23/24, will print out the Calendar's timezone, followed by the UID, timezone, DTSTART, and calculated DTSTART_tz of all events with timezones in the example/ICal.ics file (and then stop outputting the rest of the file):

echo "Calendar timezone: " . $ical->calendarTimeZone() . "\n";
foreach ($ical->sortEventsWithOrder($ical->events()) as $event) {
    if (!isset($event->dtstart_array[0]['TZID'])) {
        continue;
    }
    echo $event->uid . ", " . $event->dtstart_array[0]['TZID'] . ", " . $event->dtstart_array[1] . ", " . $event->dtstart_tz . "\n";
}
die();

Doing this twice, once without the patch and once with, will give results for before and after. Which, once checked to make sure we're lining up the correct events with each other, results in the following table (UIDs have been omitted, otherwise this table would be twice as wide as it currently is):

Calendar timezone: UTC.

DTSTART's TZID DTSTART DTSTART_tz before DTSTART_tz after
America/Los_Angeles 19410512 19410511T160000 19410512T080000
(UTC-05:00) Eastern Time (US & Canada) 20160409T090000 20160409T050000 20160409T130000
(UTC-05:00) Eastern Time (US & Canada) 20160416T090000 20160416T050000 20160416T130000
(UTC-05:00) Eastern Time (US & Canada) 20160423T090000 20160423T050000 20160423T130000
(UTC-05:00) Eastern Time (US & Canada) 20160430T090000 20160430T050000 20160430T130000
(UTC-05:00) Eastern Time (US & Canada) 20160507T090000 20160507T050000 20160507T130000
(UTC-05:00) Eastern Time (US & Canada) 20160514T090000 20160514T050000 20160514T130000
(UTC-05:00) Eastern Time (US & Canada) 20160521T090000 20160521T050000 20160521T130000
(UTC-05:00) Eastern Time (US & Canada) 20160604T090000 20160604T050000 20160604T130000
(UTC-05:00) Eastern Time (US & Canada) 20160611T090000 20160611T050000 20160611T130000
(UTC-05:00) Eastern Time (US & Canada) 20160618T090000 20160618T050000 20160618T130000
(UTC-05:00) Eastern Time (US & Canada) 20160702T090000 20160702T050000 20160702T130000
(UTC-05:00) Eastern Time (US & Canada) 20160716T090000 20160716T050000 20160716T130000
(UTC-05:00) Eastern Time (US & Canada) 20160730T090000 20160730T050000 20160730T130000
(UTC-05:00) Eastern Time (US & Canada) 20160806T090000 20160806T050000 20160806T130000
(UTC-05:00) Eastern Time (US & Canada) 20160813T090000 20160813T050000 20160813T130000
Europe/Paris 20160921T080000 20160921T100000 20160921T060000
Germany/Berlin 20170123 20170123T000000 20170123T000000
Germany/Berlin 20170220T000000 20170220T000000 20170220T000000
Germany/Berlin 20170320T000000 20170320T000000 20170320T000000
Germany/Berlin 20170417T000000 20170417T000000 20170417T000000
Germany/Berlin 20170522T000000 20170522T000000 20170522T000000
Australia/Sydney 20170813T190000 20170814T050000 20170813T090000
Australia/Sydney 20171008T190000 20171009T060000 20171008T080000

From this, we should be able to go down the list and check ouput sanity.

The first event in the list is pre-1970, and in Los Angeles over in the U.S.. According to this online resource, on that date Los Angeles was eight-hours behind GMT/UTC, and thus the generated DTSTART_tz looks correct.

The next batch of events, all occurrences of the same starting event, have a CLDR timezone that mentions a -5 hr offset from UTC. Thus, transposing from local time to UTC, I would have expected the UTC time to be five hours ahead of Local time. However it isn't; instead being only four.

Looking closer at how the parser handles this, the parser maps the given timezone to the IANA timezone America/New_York. At the given points in time (or at least the first one), New York was in "Eastern Daylight Time" ("EDT") or UTC-4. So this off-by-one-hour error appears to be more of a quirk or bug in the mapping from CLDR to IANA than an error in this patch.

Taking that into account, and assuming a UTC-4 offset (instead of the UTC-5 expected from the name of the timezone), the resultant dates look correct.

Europe/Paris, on the date given, was in daylight-savings: specifically "Central Europe Savings Time" ("CEST") which is UTC+2. So at 08:00 in the morning local time, UTC would have been two hours behind, at 06:00.

Germany/Berlin is not a valid timezone - IANA, CLDR, or Windows - so the parser defaults to the calendar's timezone. Thus, no conversion is made.

And finally, Australia/Sydney: the first date sits within "Australian Eastern Standard Time" (or AEST), whilst the second within Australian Eastern Dayliight Time (AEDT). These are UTC+10 and UTC+11 respectively. So with the local time being 19:00 for both, the expected output should be 09:00 and 08:00 respectively.

@u01jmg3
Copy link
Owner

u01jmg3 commented Jul 17, 2019

Extremely thorough analysis and just what I was looking for. 👍

To confirm, your patch has not negatively affected the 24 events listed and in some cases has corrected the time zone output?

@s0600204
Copy link
Collaborator Author

I believe so, yes.

@u01jmg3 u01jmg3 merged commit 14c2057 into u01jmg3:master Jul 17, 2019
@u01jmg3 u01jmg3 added this to the v2.x.x milestone Jul 17, 2019
@s0600204 s0600204 deleted the issues-197-and-208 branch July 17, 2019 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants