У меня есть дата начала и дата окончания.
Мне нужно узнать день, который находится в воскресенье или понедельник и т.д., в зависимости от того, установлен ли пользователь на флажке.
Как я могу найти/вычислить это в PHP?
У меня есть дата начала и дата окончания.
Мне нужно узнать день, который находится в воскресенье или понедельник и т.д., в зависимости от того, установлен ли пользователь на флажке.
Как я могу найти/вычислить это в PHP?
Вы можете создать функцию, которая использует strtotime() рекурсивно, чтобы подсчитать количество дней. Поскольку strtotime("next monday");
работает просто отлично.
function daycount($day, $startdate, $counter)
{
if($startdate >= time())
{
return $counter;
}
else
{
return daycount($day, strtotime("next ".$day, $startdate), ++$counter);
}
}
echo daycount("monday", strtotime("01.01.2009"), 0);
Надеюсь, это то, что вы ищете:)
нет циклов и нет рекурсивности
<?php
define('ONE_WEEK', 604800); // 7 * 24 * 60 * 60
function number_of_days($days, $start, $end) {
$w = array(date('w', $start), date('w', $end));
$x = floor(($end-$start)/ONE_WEEK);
$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;
}
//$start = $end = time();
// 0x10 == pow(2, 4) == 1 << 4 // THURSDAY
// 0x20 == pow(2, 5) == 1 << 5 // FRIDAY
echo number_of_days(0x01, $start, $end); // SUNDAY
echo number_of_days(pow(2, 0), $start, $end); // SUNDAY
echo number_of_days(0x02, $start, $end); // MONDAY
echo number_of_days(pow(2, 1), $start, $end); // MONDAY
echo number_of_days(0x04, $start, $end); // TUESDAY
echo number_of_days(1 << 2, $start, $end); // TUESDAY
echo number_of_days(0x08, $start, $end); // WEDNESDAY
echo number_of_days(1 << 3, $start, $end); // WEDNESDAY
echo number_of_days(0x10, $start, $end); // THURSDAY
echo number_of_days(0x20, $start, $end); // FRIDAY
echo number_of_days(0x40, $start, $end); // SATURDAY
echo number_of_days(0x01 | 0x40, $start, $end); // WEEKENDS : SUNDAY | SATURDAY
echo number_of_days(0x3E, $start, $end); // WORKDAYS : MONDAY | TUESDAY | WEDNESDAY | THURSDAY | FRIDAY
?>
Ответ w35I3y был почти правильным, но я получал ошибки с помощью этой функции. Эта функция правильно вычисляет количество понедельников или любой конкретный день между двумя датами:
/**
* Counts the number occurrences of a certain day of the week between a start and end date
* The $start and $end variables must be in UTC format or you will get the wrong number
* of days when crossing daylight savings time
* @param - $day - the day of the week such as "Monday", "Tuesday"...
* @param - $start - a UTC timestamp representing the start date
* @param - $end - a UTC timestamp representing the end date
* @return Number of occurences of $day between $start and $end
*/
function countDays($day, $start, $end)
{
//get the day of the week for start and end dates (0-6)
$w = array(date('w', $start), date('w', $end));
//get partial week day count
if ($w[0] < $w[1])
{
$partialWeekCount = ($day >= $w[0] && $day <= $w[1]);
}else if ($w[0] == $w[1])
{
$partialWeekCount = $w[0] == $day;
}else
{
$partialWeekCount = ($day >= $w[0] || $day <= $w[1]);
}
//first count the number of complete weeks, then add 1 if $day falls in a partial week.
return floor( ( $end-$start )/60/60/24/7) + $partialWeekCount;
}
Пример использования:
$start = strtotime("tuesday UTC");
$end = strtotime("3 tuesday UTC");
echo date("m/d/Y", $start). " - ".date("m/d/Y", $end). " has ". countDays(0, $start, $end). " Sundays";
Выводит что-то вроде: 29.09.2010 - 10/19/2010 имеет 3 воскресенья.
Этот вопрос просто кричит об обновленном ответе, в котором используются классы PHP DateTime, поэтому вот оно: -
/**
* @param String $dayName eg 'Mon', 'Tue' etc
* @param DateTimeInterface $start
* @param DateTimeInterface $end
* @return int
*/
function countDaysByName($dayName, \DateTimeInterface $start, \DateTimeInterface $end)
{
$count = 0;
$interval = new \DateInterval('P1D');
$period = new \DatePeriod($start, $interval, $end);
foreach($period as $day){
if($day->format('D') === ucfirst(substr($dayName, 0, 3))){
$count ++;
}
}
return $count;
}
<?php
$date = strtotime('2009-01-01');
$dateMax = strtotime('2009-02-23');
$nbr = 0;
while ($date < $dateMax) {
var_dump(date('Y-m-d', $date));
$nbr++;
$date += 7 * 24 * 3600;
}
echo "<pre>";
var_dump($nbr);
?>
$from_date=(2015-01-01);
$to_date=(2015-01-20);
while(strtotime($from_date) <= strtotime($to_date)){
//5 for count Friday, 6 for Saturday , 7 for Sunday
if(date("N",strtotime($from_date))==5){
$counter++;
}
$from_date = date ("Y-m-d", strtotime("+1 day", strtotime($from_date)));
}
echo $counter;
function daycount($day, $startdate, $enddate, $counter) {
if($startdate >= $enddate) {
return $counter-1; // A hack to make this function return the correct number of days.
} else {
return $this->daycount($day, strtotime("next ".$day, $startdate), $enddate, ++$counter);
}
}
Это другая версия первого ответа, которая принимает начальную и конечную точку и работает для меня. Все примеры, приведенные на этой странице, по какой-то причине возвращали ответ плюс дополнительный день.
w35l3y ответ, похоже, работает хорошо, поэтому я проголосовал за него. Тем не менее, я предпочел что-то немного легче следовать, и с меньшей математикой и циклом (не уверен, что это имеет значение с точки зрения производительности, хотя). Я думаю, что я рассмотрел все возможные сценарии... Вот что я придумал:
function numDays($sday, $eday, $i, $cnt) {
if (($sday < $eday && $i >= $sday && $i <= $eday) || ($sday > $eday && ($i >= $sday || $i <= $eday))) {
// partial week (implied by $sday != $eday), so $i (day iteration) may have occurred one more time
// a) end day is ahead of start day; $i is within start/end of week range
// b) start day is ahead of end day (i.e., Tue start, Sun end); $i is either in back half of first week or front half of second week
$cnt++;
} elseif ($sday == $eday && $i == $sday) {
// start day and end day are the same, and $i is that day, i.e., Tue occurs twice from Tue-Tue (1 wk, so $wks = $cnt)
$cnt++;
}
return $cnt; // # of complete weeks + partial week, if applicable
}
Примечания: $sday и $eday - это числа дня, соответствующие началу и концу проверяемого диапазона, а $i - подсчитываемый номер дня (у меня это в цикле 0-6). Я переместил $wks вне функции, так как нет никакой точки, пересчитывающей ее каждый раз.
$wks = floor(($endstamp - $startstamp)/7*24*60*60);
$numDays = numDays($sday, $eday, $i, $wks);
Убедитесь, что метки времени начала/конца, которые вы сравниваете, имеют одинаковую регулировку часового пояса, если таковые имеются, в противном случае вы всегда будете немного отставать от $cnt и $wks. (Я столкнулся с этим, когда рассчитывал с нескорректированной первой в год на скорректированный день/время X.)
Я получил ответ. Он работает только в воскресенье. Но я не знаю, как сделать это в течение других дней.
"; $ days_until_sunday = date ('w', $start) > 0? 7 - дата ('w', $start): 0; $ date = $start + (ONE_DAY * $days_until_sunday); $ sundays = array(); while ($ date); $ Кол = 0; // Цикл и выход Y-m-d foreach (sundays_in_range ($ start, $end) как $sunday) { print ".date(" Y-m-d ", $sunday)."