Как получить интервал дат для каждой недели в данном месяце? - PullRequest
3 голосов
/ 29 ноября 2011

Есть ли способ получить дату начала / окончания каждой недели в PHP, которая дается месяц? Так, например, если я возьму этот месяц (ноябрь 2011), мне нужно вернуть

30 Oct ->  5 Nov
 6 Nov -> 12 Nov
13 Nov -> 19 Nov
20 Nov -> 26 Nov
27 Nov ->  3 Dec

LE:

Вот что я сделал на случай, если кому-то еще это понадобится. Код не очень красивый, но работает так, как мне нужно.

public function getMonthWeeks($month, $year)
{
    $month = intval($month);

    if ($month < 1) {
        $month = 1;
    }

    if ($month > 12) {
        $month = 12;
    }

    $tsfdOfMonth = mktime(0, 0, 0, $month, 1, $year);
    $dayOfWeek   = idate('w', $tsfdOfMonth);

    $tIntervalStart = $tsfdOfMonth;
    $tNextMonth     = idate('m', strtotime("+1 month", $tsfdOfMonth));

    if ($dayOfWeek > 0) {
        $tStr = sprintf("-%d %s",
            $dayOfWeek,
            $dayOfWeek == 1 ? 'day' : 'days'
        );
        $tIntervalStart = strtotime($tStr, $tsfdOfMonth);
    }

    $resultDates = array();

    $tsStart = $tIntervalStart;
    $tsEnd   = strtotime('+6 days', $tsStart);

    while (true) {
        $rObj = new stdClass;
        $rObj->LinkStr = sprintf("%s %s - %s %s",
            date('M', $tsStart), date('d', $tsStart),
            date('M', $tsEnd),   date('d', $tsEnd)
        );
        $rObj->DateStart = date('Y-m-d', $tsStart);
        $rObj->DateEnd   = date('Y-m-d', $tsEnd);

        $resultDates[] = $rObj;

        if (idate('m', strtotime('+1 day',  $tsEnd)) == $tNextMonth) {
            break;
        }

        $tsStart = strtotime('+1 day',  $tsEnd);
        $tsEnd   = strtotime('+6 days', $tsStart);
    }

    return $resultDates;
}

Ответы [ 4 ]

4 голосов
/ 29 ноября 2011

Вам нужно написать функцию:

Алгоритм:

  1. Получить день недели первого месяца.
  2. Вычтите необходимое количество дней, чтобы достичь воскресенья - теперь у вас есть дата первого «воскресенья» месяца (возможно, последнее воскресенье предыдущего месяца).
  3. Добавьте шесть дней, чтобы определить субботу этой недели.
  4. Добавьте один день, чтобы определить воскресенье следующей недели.
  5. повторите 3 и 4, пока мы не перестанем быть в текущем месяце

Очень полезны две функции: $saturdaytimestamp = strtotime("+6 days", $sundaytimestamp) и $dayofweek = idate('w', $timestamp);

2 голосов
/ 29 ноября 2011

Вы должны использовать эти функции - cal_days_in_month, strtotime, date

$aMonthWeeks = get_month_week_day_ranges(2011, 11);
print_r( $aMonthWeeks );

function get_month_week_day_ranges ( $year, $month ) {
    $last_month_day_num = cal_days_in_month(CAL_GREGORIAN, $month, $year); 

    $first_month_day_timestamp = strtotime($year.'-'.$month.'-01');
    $last_month_daty_timestamp = strtotime($year.'-'.$month.'-'.$last_month_day_num );

    $first_month_week = date('W', $first_month_day_timestamp);
    $last_month_week = date('W', $last_month_daty_timestamp);

    $aMonthWeeks = array();
    for( $week = $first_month_week; $week <= $last_month_week; $week ++ ) {
        echo sprintf('%dW%02d-1', $year, $week ), "\n";
        array_push( $aMonthWeeks, array(  
            date("d:m:Y", strtotime( sprintf('%dW%02d-1', $year, $week ) ) ),
            date("d:m:Y", strtotime( sprintf('%dW%02d-7', $year, $week ) ) ),
        ) );
    }
    return $aMonthWeeks;
}

Для моей локали (первый день недели понедельник ) результат равен

Array
(
    [0] => Array
        (
            [0] => 31:10:2011
            [1] => 06:11:2011
        )

    [1] => Array
        (
            [0] => 07:11:2011
            [1] => 13:11:2011
        )

    [2] => Array
        (
            [0] => 14:11:2011
            [1] => 20:11:2011
        )

    [3] => Array
        (
            [0] => 21:11:2011
            [1] => 27:11:2011
        )

    [4] => Array
        (
            [0] => 28:11:2011
            [1] => 04:12:2011
        )

)
1 голос
/ 29 ноября 2011

Я не знаю, каков наилучший способ сделать это, но это может сработать: вы спрашиваете PHP, какой день недели является первым днем ​​месяца, например date('w', mktime(0, 0, 0, (int)date('m'), 1, (int)date('Y'));, а затем вы можете отсчитывать до первого дня неделю, используйте функцию checkdate(), чтобы определить последний день предыдущего месяца, затем создайте массив с простым while(), пока не достигнете недели, которую вы заканчиваете, но не начинаете в следующем месяце.

0 голосов
/ 29 ноября 2011

Я просто потратил время, чтобы написать это для вас, и это выведет то, что вы хотите:

<?php

/* CONFIG */

$year = 2011;

$month = 11;

/* CODE */

$first_day = mktime(0, 0, 0, $month, 1, $year);

$month_first_day = date('w', $first_day);

if($month_first_day != 1) {

    $offset = $month_first_day - 1;

    $previous_month = ($month == 1 ? mktime(0, 0, 0, 12, 1, ($year - 1)) : mktime(0, 0, 0, ($month - 1), 1, $year));

    $previous_month_days = date('t', $previous_month);

    $previous_month_saturday = $previous_month_days - $offset;

    $previous_month_stamp = ($month == 1 ? mktime(0, 0, 0, 12, $previous_month_saturday, ($year - 1)) : mktime(0, 0, 0, ($month - 1), $previous_month_saturday, $year));

    $first_saturday = $previous_month_stamp;

}else{

    $first_saturday = $first_day;

}

$loops = date('t', $first_day);

$loops = round($loops / 7);

for($loop = 1; $loop < ($loops + 2); $loop++) {

    echo date('j M', $first_saturday + ((7 * ($loop - 1)) * 24 * 60 * 60)) . ' -> ' . date('j M', $first_saturday + (((7 * $loop) - 1) * 24 * 60 * 60)) . '<br />';

}

Возможно, это не самый эффективный способ достижения цели.Однако он получает то, о чем вы просили, и дает общее представление о том, как этого можно достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...