В PHP, как узнать, сколько понедельников прошло в этом месяце до сегодняшнего дня?

Предположим, что сегодня 21 февраля 2011 года (понедельник). Это третий понедельник этого месяца. Если в качестве входных данных задана дата, как я могу узнать, сколько понедельников прошло до нее?

В PHP, как узнать, сколько понедельников прошло в этом месяце до сегодняшнего дня?


person Salman Virk    schedule 21.02.2011    source источник


Ответы (6)


$now=time() + 86400;
if (($dow = date('w', $now)) == 0) $dow = 7; 
$begin = $now - (86400 * ($dow-1));

echo "Mondays: ".ceil(date('d', $begin) / 7)."<br/>";

работает на меня....

РЕДАКТИРОВАТЬ: включает и сегодняшний понедельник

person david.wosnitza    schedule 21.02.2011

Это звучит как довольно простой расчет деления. Из текущей даты вычтите количество дней, прошедших с прошлого понедельника (пример: среда = -2), разделите его на 7 и ceil(), чтобы округлить в большую сторону.

РЕДАКТИРОВАТЬ: это будет включать текущий понедельник в число, возвращая «3» для понедельника 21-го.

person Kaivosukeltaja    schedule 21.02.2011
comment
Работает для 21 февраля, но не для 1 февраля. Если бы в качестве примера он использовал 01.02.2011, вы бы вернули 1 для вторника 1 февраля (или, если он не осторожен, он мог бы вернуть номер понедельника). в январе). - person Farray; 21.02.2011
comment
Моя ошибка, плохой выбор слов. Под датой я подразумеваю день месяца. Таким образом, вычитание единицы (потому что сегодня вторник) из единицы дает ноль, который округляется до нуля. - person Kaivosukeltaja; 22.02.2011
comment
Верно, основная формула ceil( day_of_month / 7 ). Но вам нужно вычесть дни (-2 для ср в вашем примере), так как он попросил понедельники. - person Justin Ethier; 04.08.2011
comment
@Justin: Да, я считаю, что это упомянуто в моем ответе. :) - person Kaivosukeltaja; 04.08.2011
comment
@Kaivosukeltaja: Согласен :) - Извините за плохую формулировку во второй половине моего комментария. Я просто пытался помочь мне понять, что здесь происходит... возможно, это поможет следующему парню, возможно, нет... - person Justin Ethier; 04.08.2011

    <?php

 function mondays_get($month, $stop_if_today = true) {

$timestamp_now = time();

for($a = 1; $a < 32; $a++) {

    $day = strlen($a) == 1 ? "0".$a : $a;
    $timestamp = strtotime($month . "-$day");
    $day_code = date("w", $timestamp);
    if($timestamp > $timestamp_now)
        break;
    if($day_code == 1)
        @$mondays++;

}

return $mondays;
}

echo mondays_get('2011-02');

Надеюсь, это вам пригодится! я только что свернул его.

«Остерегайтесь ошибок в приведенном выше коде; я только доказал его правильность, а не пробовал».

Работает нормально

person Pedro    schedule 21.02.2011

Вы можете просмотреть все дни до сих пор и посчитать понедельники:

$firstDate = mktime(0, 0, 0, date("n"), 1, date("Y"));
$now = time();
$mondays = 0;
for ($i = $firstDate; $i < $now; $i = $i + 24*3600) {
    if (date("D", $i) == "Mon")
        $mondays ++;
}

Не тестировал этот скрипт

person Robin    schedule 21.02.2011
comment
Используя этот подход, мы можем зацикливаться, получая последний понедельник, пока дата last monday не будет принадлежать предыдущему месяцу. - person Salman Virk; 21.02.2011
comment
Исправлен скрипт, j должен был быть n. Теперь это работает, но я бы все же предпочел решение Кайвосукельтаи, гораздо проще сделать это с помощью базовой математики. - person Robin; 21.02.2011

Попробуй это...

//find the most recent monday (doesn't find today if today is Monday though)
$startDate = strtotime( 'last monday' );

//if 'last monday' was not this month, 0 mondays.  
//if 'last monday' was this month, count the weeks
$mondays = date( 'm', $startDate ) != date( 'm' ) 
         ? 0 
         : floor( date( 'd', $startDate ) / 7 );

//increment the count if today is a monday (since strtotime didn't find it)
if ( date( 'w' ) == 1 ) $mondays++;
person Farray    schedule 21.02.2011

Другой способ — узнать, какой сегодня день недели, найти первый такой день месяца с помощью какой-то магии strtotime(), а затем вычислить разницу между этим и сегодняшним днем ​​в неделях. См. ниже функцию, которая будет принимать date() в формате Y-m-d и возвращать текущий день недели месяца.

Примечание. strtotime должен быть подробным, включая "из" и месяц: "первый понедельник 2011-02", иначе он передвигается на один день. Это укусило меня, когда я тестировал крайние случаи.

Также добавил немного перца дисплея, который совершенно необязателен, но мне захотелось.

function nthWeekdayOfMonth($day) {

    $dayTS = strtotime($day) ;

    $dayOfWeekToday = date('l', $dayTS) ;

    $firstOfMonth = date('Y-m', $dayTS) . "-01" ;
    $firstOfMonthTS = strtotime($firstOfMonth) ;

    $firstWhat = date('Y-m-d', strtotime("first $dayOfWeekToday of $monthYear", $firstOfMonthTS)) ;
    $firstWhatTS = strtotime($firstWhat) ;

    $diffTS = $dayTS - $firstWhatTS ;
    $diffWeeks = $diffTS / (86400 * 7);

    $nthWeekdayOfMonth = $diffWeeks + 1;

    return $nthWeekdayOfMonth ;
}

$day = date('Y-m-d') ;
$nthWeekdayOfMonth = nthWeekdayOfMonth($day) ;

switch ($nthWeekdayOfMonth) {
    case 1: 
        $inflector = "st" ;
        break ;
    case 2: 
        $inflector = "nd" ;
        break ;
    case 3: 
        $inflector = "rd" ;
        break ;
    default:
        $inflector = "th" ;
}

$dayTS = strtotime($day) ;

$monthName = date('F', $dayTS) ;    
$dayOfWeekToday = date('l', $dayTS) ;

echo "Today is the {$nthWeekdayOfMonth}$inflector $dayOfWeekToday in $monthName" ;
person Fanis Hatzidakis    schedule 21.02.2011