Skip to content

Commit

Permalink
Improve handling of Events defined with a DURATION
Browse files Browse the repository at this point in the history
Use correct object when populating `BYMONTHDAY` Event data
  • Loading branch information
u01jmg3 committed Dec 16, 2016
1 parent 48d285b commit 93ee33e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ $ curl -s https://getcomposer.org/installer | php
| `iCalDateToUnixTimestamp` | `$icalDate`, `$useTimeZone` | Return Unix timestamp from iCal date time format |
| `iCalDateWithTimeZone` | `$event`, `$key` | Return a date adapted to the calendar timezone depending on the event TZID |
| `isValidTimeZoneId` | `$timezone` | Check if a timezone is valid |
| `parseDuration` | `$date`, `$duration` | Parse a duration and apply it to a date |
| `processDateConversions` | - | Add fields `DTSTART_tz` and `DTEND_tz` to each event |
| `processEvents` | - | Performs some admin tasks on all events as taken straight from the ics file. |
| `processRecurrences` | - | Processes recurrence rules |
Expand Down
58 changes: 42 additions & 16 deletions src/ICal/ICal.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,15 @@ public function iCalDateWithTimeZone($event, $key)
$date_array = $event[$key . '_array'];
$date = $event[$key];

if ($key === 'DURATION') {
$duration = end($date_array);
$timestamp = $this->parseDuration($event['DTSTART'], $duration);
$dateTime = \DateTime::createFromFormat('U', $timestamp);
$date = $dateTime->format(self::DATE_TIME_FORMAT);
} else {
$dateTime = new \DateTime($date);
}

if (isset($date_array[0]['TZID']) && preg_match('/[a-z]*\/[a-z_]*/i', $date_array[0]['TZID'])) {
$timeZone = $date_array[0]['TZID'];
}
Expand Down Expand Up @@ -619,14 +628,7 @@ public function processRecurrences()
$endTimestamp = $initialEnd->getTimestamp();
} else if (isset($anEvent['DURATION'])) {
$duration = end($anEvent['DURATION_array']);
$endTimestamp = date_create($anEvent['DTSTART']);
$endTimestamp->modify($duration->y . ' year');
$endTimestamp->modify($duration->m . ' month');
$endTimestamp->modify($duration->d . ' day');
$endTimestamp->modify($duration->h . ' hour');
$endTimestamp->modify($duration->i . ' minute');
$endTimestamp->modify($duration->s . ' second');
$endTimestamp = date_format($endTimestamp, 'U');
$endTimestamp = $this->parseDuration($anEvent['DTSTART'], $duration);
} else {
$endTimestamp = $anEvent['DTSTART_array'][2];
}
Expand Down Expand Up @@ -859,20 +861,22 @@ public function processRecurrences()
foreach ($monthdays as $key => $monthday) {
if ($key === 0) {
// Ensure original event conforms to monthday rule
$events[0]['DTSTART'] = gmdate(
$anEvent['DTSTART'] = gmdate(
'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
strtotime($events[0]['DTSTART'])
strtotime($anEvent['DTSTART'])
) . ($isAllDayEvent || $initialStartTimeZoneName === 'Z' ? 'Z' : '');

$events[0]['DTEND'] = gmdate(
$anEvent['DTEND'] = gmdate(
'Ym' . sprintf('%02d', $monthday) . '\T' . self::TIME_FORMAT,
strtotime($events[0]['DTEND'])
isset($anEvent['DURATION'])
? $this->parseDuration($anEvent['DTSTART'], end($anEvent['DURATION_array']))
: strtotime($anEvent['DTEND'])
) . ($isAllDayEvent || $initialEndTimeZoneName === 'Z' ? 'Z' : '');

$events[0]['DTSTART_array'][1] = $events[0]['DTSTART'];
$events[0]['DTSTART_array'][2] = $this->iCalDateToUnixTimestamp($events[0]['DTSTART']);
$events[0]['DTEND_array'][1] = $events[0]['DTEND'];
$events[0]['DTEND_array'][2] = $this->iCalDateToUnixTimestamp($events[0]['DTEND']);
$anEvent['DTSTART_array'][1] = $anEvent['DTSTART'];
$anEvent['DTSTART_array'][2] = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
$anEvent['DTEND_array'][1] = $anEvent['DTEND'];
$anEvent['DTEND_array'][2] = $this->iCalDateToUnixTimestamp($anEvent['DTEND']);

// Ensure recurring timestamp confirms to BYMONTHDAY rule
$monthRecurringTimestamp = $this->iCalDateToUnixTimestamp(
Expand Down Expand Up @@ -1151,6 +1155,8 @@ public function processDateConversions()

if ($this->iCalDateWithTimeZone($anEvent, 'DTEND')) {
$events[$key]['DTEND_tz'] = $this->iCalDateWithTimeZone($anEvent, 'DTEND');
} else if ($this->iCalDateWithTimeZone($anEvent, 'DURATION')) {
$events[$key]['DTEND_tz'] = $this->iCalDateWithTimeZone($anEvent, 'DURATION');
}
}

Expand Down Expand Up @@ -1392,4 +1398,24 @@ function isValidTimeZoneId($timezone){

return (isset($valid[$timezone]));
}

/**
* Parse a duration and apply it to a date
*
* @param string $date A date to add a duration to
* @param \DateInterval $timezone A duration to parse
* @return integer Unix timestamp
*/
function parseDuration($date, $duration){
$timestamp = date_create($date);
$timestamp->modify($duration->y . ' year');
$timestamp->modify($duration->m . ' month');
$timestamp->modify($duration->d . ' day');
$timestamp->modify($duration->h . ' hour');
$timestamp->modify($duration->i . ' minute');
$timestamp->modify($duration->s . ' second');
$timestamp = date_format($timestamp, 'U');

return $timestamp;
}
}

0 comments on commit 93ee33e

Please sign in to comment.