Given a date, get the next or previous Monday, or Tuesday etc from the given date. This is useful when working with ical recurring dates. If the date given is already that day of week, it is returned as the result.
For example to get the following
Every 20th Monday of the year, forever:
DTSTART;TZID=US-Eastern:19970519T090000
RRULE:FREQ=YEARLY;BYDAY=20MO==> (1997 9:00 AM EDT)May 19
(1998 9:00 AM EDT)May 18
(1999 9:00 AM EDT)May 17
One could get the first Monday of the year, the it is fairly easy to get the 20th !
<?php
global $amr_day_of_week_no;
$amr_day_of_week_no = array (
'MO' => 1,
'TU' => 2,
'WE' => 3,
'TH' => 4,
'FR' => 5,
'SA' => 6,
'SU' => 0
);
function amr_goto_byday ($dateobj, $byday, $sign) {
global $amr_day_of_week_no;
$dayofweek = $dateobj->format('w'); /* 0=sunday, 6 = saturday */
if ($dayofweek == '-1') $dayofweek = get_oldweekdays($dateobj); /* php seems to break around 1760 */
$target = $amr_day_of_week_no[$byday]; /* mo=1 ,su=7 */
$adjustment = $target - $dayofweek;
if ($sign === '+') {
if ($adjustment < 0) $adjustment = $adjustment + 7;
}
else if ($adjustment > 0) $adjustment = $adjustment-7;
$d2 = new DateTime();
$d2 = clone ($dateobj);
date_modify ($d2,$adjustment.' days');
return ($d2);
}
/* --------Test data ------------------------- */
$d[] = new DateTime('2009-12-25');
$d[] = new DateTime('2009-12-28');
$d[] = new DateTime('2009-12-29');
$d[] = new DateTime('2009-12-30');
$d[] = new DateTime('2009-12-31');
$d[] = new DateTime('2010-01-01');
$d[] = new DateTime('2010-01-02');
$d[] = new DateTime('2010-01-03');
$d[] = new DateTime('2010-01-04');
$d[] = new DateTime('2010-01-05');
$d[] = new DateTime('2010-01-06');
$d[] = new DateTime('2010-01-07');
$d[] = new DateTime('2010-01-08');
$d[] = new DateTime('2010-01-09');
$d[] = new DateTime('2010-01-10');
$d[] = new DateTime('2010-01-11');
echo '<table>';
foreach (array ('TU','WE','TH','FR','SA','SU','MO') as $day) {
echo '<tr><td> Aiming for '.$day.'</td><td>If not this, then next</td><td>If not this, then prev</td></tr>';
foreach ($d as $i => $d2) {
$d3 = amr_goto_byday ($d2, $day, '+');
$d4 = amr_goto_byday ($d2, $day, '-');
$s = $d2->format('Y m d l');
echo '<tr><td> '.$s.'</td><td>'.$d3->format('l,Y m d').'</td><td>'.$d4->format('l,Y m d').'</td></tr>';
}
}
echo '</table>';
?>
Related posts:
- Calculate date from day of year in php Here is a simple first of several notes on useful date functions. This function accepts a year (YYYY) and a...
- Day of week for historical dates earlier than 1760 Problem with getting the day of week for old dates before 1760? See this....
- Timezones and offsets in wordpress Writing a plugin that requires a correct timezone object ? Not sure how to deal with wordpress installations that may...



