daniels
daniels

Reputation: 19203

How to get the date interval for each week in a given month?

Is there a way to get the date start/end for each week in PHP given a month? So for example if i take this month(Nov 2011) i need to return

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

LE:

Here's what i made in case some one else needs it. The code is not pretty but it works as i need it.

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;
}

Upvotes: 3

Views: 2915

Answers (4)

Josh Foskett
Josh Foskett

Reputation: 4121

I just took the time to code this for you, and this will output what you want:

<?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 />';

}

This may not be the most effective way of achieving the goal. However, it gets what you've asked for done, and it gives you a general idea of how this could be accomplished.

Upvotes: 0

ZuRom
ZuRom

Reputation: 91

You should use these functions - 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;
}

For my locale (the first day of week is monday) the result is

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
        )

)

Upvotes: 2

Francis Avila
Francis Avila

Reputation: 31621

You will have to write a function:

Algorithm:

  1. Get day of week of first of month.
  2. Subtract necessary number of days to reach a Sunday--you now have date of the first "sunday" of the month (possibly last sunday of previous month).
  3. Add six days to determine the Saturday of that week.
  4. Add one day to determine the Sunday of the next week.
  5. repeat 3 and 4 until we are no longer in the current month

Two features will be very helpful: $saturdaytimestamp = strtotime("+6 days", $sundaytimestamp) and $dayofweek = idate('w', $timestamp);

Upvotes: 4

r1pp3rj4ck
r1pp3rj4ck

Reputation: 1487

I do not know what the best way to do this is, but this could work: you ask PHP what day of week is the first day of the month like date('w', mktime(0, 0, 0, (int)date('m'), 1, (int)date('Y')); and then you can count down to the first day of the week, use the checkdate() function to determine the last day of the previous month, then build your array with a simple while() until you reach a week you ending but not starting in the next month.

Upvotes: 1

Related Questions