You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-1 is already supported as by using relative date formats we can use 'last day of ...'; however anything less than -1 won't work because penultimate, etc. is not offered with relative date formats
For example:
FREQ=MONTHLY;BYDAY=-2MO;COUNT=7
Every month on the 2nd last Monday for 7 times
FREQ=YEARLY;BYDAY=-3SU;BYMONTH=10
Every October on the 3rd last Sunday
The code below will convert a negative BYDAY value such as -2MO to its appropriate positive day ordinal such as the 'third'.
Will leave the implementation to someone else but this snippet should provide a start.
<?php/** * Get the number of days between a * start and end date * * @param $days * @param $start * @param $end * @return integer */functionnumberOfDays($days, $start, $end){
$w = array(date('w', $start), date('w', $end));
$oneWeek = 604800; // 7 * 24 * 60 * 60$x = floor(($end - $start) / $oneWeek);
$sum = 0;
for ($day = 0; $day < 7; ++$day) {
if ($days & pow(2, $day)) {
$sum += $x + ($w[0] > $w[1] ? $w[0] <= $day || $day <= $w[1] : $w[0] <= $day && $day <= $w[1]);
}
}
return$sum;
}
/** * Convert a negative day ordinal to * its equivalent positive form * * @param $dayNumber * @param $weekday * @param $timestamp * @return string */functionconvertDayOrdinalToPositive($dayNumber, $weekday, $timestamp){
$dayNumber = empty($dayNumber) ? 1 : $dayNumber; // Returns 0 when no number defined in BYDAY$dayOrdinals = array(1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth');
// We only care about negative BYDAY valuesif ($dayNumber >= 1) {
return$dayOrdinals[$dayNumber];
}
$timestamp = (is_object($timestamp)) ? $timestamp : \DateTime::createFromFormat('U', $timestamp);
$start = strtotime('first day of ' . $timestamp->format('F Y H:i:s'));
$end = strtotime('last day of ' . $timestamp->format('F Y H:i:s'));
// Used with pow(2, X) so pow(2, 4) is THURSDAY$weekdays = array('SU' => 0, 'MO' => 1, 'TU' => 2, 'WE' => 3, 'TH' => 4, 'FR' => 5, 'SA' => 6);
$numberOfDays = numberOfDays(pow(2, $weekdays[$weekday]), $start, $end);
// Create subset$dayOrdinals = array_slice($dayOrdinals, 0, $numberOfDays, true);
//Reverse only the values$dayOrdinals = array_combine(array_keys($dayOrdinals), array_reverse(array_values($dayOrdinals)));
return$dayOrdinals[$dayNumber * -1];
}
echo convertDayOrdinalToPositive(-2, 'MO', date_create('now'));
The text was updated successfully, but these errors were encountered:
u01jmg3
changed the title
Ability to parse a negative BYDAY $day_number value such as -2MO
Support ability to parse a negative BYDAY $day_number value such as -2MO, etc.
Apr 13, 2015
FREQ=MONTHLY;BYDAY=-2MO;COUNT=7
FREQ=YEARLY;BYDAY=-3SU;BYMONTH=10
-2MO
to its appropriate positive day ordinal such as the 'third'.The text was updated successfully, but these errors were encountered: