12

How to find a speciefic nearest day of the week in PHP if initially I have a date string like: 07.05.2010? For example, I want to find the nearest Sunday (or any day of the week). How can I implement this? Thanks

moogeek
  • 397
  • 4
  • 14
  • 34

7 Answers7

17

Just in case you wanted the nearest day rather than the next one, here is a way to do that.

$target = "Sunday";
$date   = "07.05.2010";

// Old-school DateTime::createFromFormat
list($dom, $mon, $year) = sscanf($date, "%02d.%02d.%04d");
$date = new DateTime("$year/$mon/$dom -4 days");
// Skip ahead to $target day
$date->modify("next $target");

echo $date->format("d.m.Y");

And as of PHP 5.3, that middle portion can be simply

$date = DateTime::createFromFormat("!d.m.Y", $date)
        ->modify("-4 days")->modify("next $target");
salathe
  • 51,324
  • 12
  • 104
  • 132
13

This should do:

echo date('d.m.Y', strtotime('next Sunday', strtotime('07.05.2010')));
Mike
  • 4,839
  • 3
  • 25
  • 22
  • Not if the latter is a german date format MM.DD.YYYY - strtotime will screw that up. You'll have to find a solution for that as well to get my upvote :) – Pekka May 06 '10 at 21:09
  • 6
    Plus, be sure to test out the edge cases. What happens if 07.05.2010 itself is a sunday? – Pekka May 06 '10 at 21:10
  • 14
    "next Sunday" is not necessarily the "nearest Sunday" – Dolph May 06 '10 at 21:11
  • ask your users to inpt the date in the proper format .. otherwise u cant find out if its 05/07 or 07/05 that the user entered – Nikola Sivkov May 06 '10 at 21:12
  • Thanks, it worked even if the date is a Sunday too. Shame on me of not knowing this 'next %dayofweek%' method for 'strtotime'... – moogeek May 06 '10 at 21:13
  • 1
    So by *nearest* you actually meant *next* ? – salathe May 06 '10 at 21:43
4
/**
 *
 * @param \DateTime $date
 * @param $dayOfWeek - e.g Monday, Tuesday ...
 */
public function findNearestDayOfWeek(\DateTime $date, $dayOfWeek)
{
    $dayOfWeek = ucfirst($dayOfWeek);
    $daysOfWeek = array(
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday',
        'Sunday',
    );
    if(!in_array($dayOfWeek, $daysOfWeek)){

        throw new \InvalidArgumentException('Invalid day of week:'.$dayOfWeek);
    }
    if($date->format('l') == $dayOfWeek){

        return $date;
    }

    $previous = clone $date;
    $previous->modify('last '.$dayOfWeek);

    $next = clone $date;
    $next->modify('next '.$dayOfWeek);

    $previousDiff = $date->diff($previous);
    $nextDiff = $date->diff($next);

    $previousDiffDays = $previousDiff->format('%a');
    $nextDiffDays = $nextDiff->format('%a');

    if($previousDiffDays < $nextDiffDays){

        return $previous;
    }

    return $next;
}

Alternatively you could create a map of what days of weeks are closer, e.g if you're after closest Monday to Wednesday, it would be faster to just find the previous Monday given that it's closer than the next Monday.

Rob Jensen
  • 261
  • 2
  • 6
1

There are several answers posted and I keep seeing solutions that could give me either the next instance of a day of the week or the previous instance but not the closest. To address this, I came up with this function:

function closestDate($day){

    $day = ucfirst($day);
    if(date('l', time()) == $day)
        return date("Y-m-d", time());
    else if(abs(time()-strtotime('next '.$day)) < abs(time()-strtotime('last '.$day)))
        return date("Y-m-d", strtotime('next '.$day));
    else
        return date("Y-m-d", strtotime('last '.$day));

}

Input: a day of the week ("sunday", "Monday", etc.)

Output: If I asked for the nearest "sunday" and today is:

  1. "Sunday": I will get today's date
  2. "Monday": I will get yesterday's date
  3. "Saturday: I will get tomorrow's date

Hope this helps :)

karancan
  • 2,152
  • 4
  • 23
  • 35
0

This can be done using only strtotime() and a little trickery.

function findNearest($day, $date)
{
    return strtotime("next $day", strtotime("$date - 4 days"));
}

echo date('d.m.Y', findNearest("Sunday", "07.05.2010")); // 09.05.2010
echo               findNearest("Sunday", "07.05.2010");  // 1273377600
echo date('d.m.Y', findNearest("Sunday", "09.05.2010")); // 09.05.2010
echo               findNearest("Sunday", "09.05.2010");  // 1273377600
echo date('d.m.Y', findNearest("Sunday", "05.05.2010")); // 02.05.2010
echo               findNearest("Sunday", "05.05.2010");  // 1272772800
Westy92
  • 19,087
  • 4
  • 72
  • 54
0

strtotime is magical

echo date("d/m/y", strtotime("next sunday", strtotime("07.05.2010")  ) );
Galen
  • 29,976
  • 9
  • 71
  • 89
0

You can use Carbon library as well

$date = Carbon::create(2015, 7, 2); // 2015-07-02

// To get the first day of the week 
$monday = $date->startOfWeek(); // 2015-06-29

$mondayTwoWeeksLater = $date->addWeek(2); // 2015-07-13
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191