Как найти ближайший день недели в PHP?
Как найти ближайший день недели в PHP, если изначально у меня есть строка даты, например:07.05.2010
? Например, я хочу найти ближайшее воскресенье (или любой день недели). Как я могу это реализовать? Спасибо
7 ответов
на всякий случай, если вы хотели ближайший день, а не далее один, вот способ сделать это.
$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");
и начиная с PHP 5.3, эта средняя часть может быть просто
$date = DateTime::createFromFormat("!d.m.Y", $date)
->modify("-4 days")->modify("next $target");
/**
*
* @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;
}
в качестве альтернативы вы можете создать карту того, какие дни недель ближе, e.g Если вы ищете ближайший понедельник к среде, было бы быстрее просто найти предыдущий понедельник, учитывая, что он ближе, чем следующий понедельник.
есть несколько ответов, и я продолжаю видеть решения, которые могут дать мне либо далее экземпляр дня недели или экземпляр но не ближе. Чтобы решить эту проблему, я придумал эту функцию:
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));
}
вход: день недели ("воскресенье", "понедельник" и т. д.)
вывод: если я попросил ближайшее "воскресенье" и сегодня:
- "воскресенье": я получу сегодня дата
- "понедельник" : я получу вчерашнюю дату
- "суббота: я получу завтрашнюю дату
надеюсь, что это помогает :)
strtotime - Это волшебный
echo date("d/m/y", strtotime("next sunday", strtotime("07.05.2010") ) );
Это можно сделать, используя только strtotime()
и немного хитрости.
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
вы также можете использовать библиотеку углерода
$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