Receiving extra 1 in january month calender

92 views Asked by At
function getDates($year){

$dates = array();

for($i = 1; $i <= 366; $i++){ 
    $month = date('m', mktime(0,0,0,1,$i,$year)); // outputs month 01 for jan etc
    $wk = date('W', mktime(0,0,0,1,$i,$year)); // this outputs 01 if 1st week etc  
    $wkDay = date('D', mktime(0,0,0,1,$i,$year)); //weekday eg mon ,sun etc
    echo $day = date('d', mktime(0,0,0,1,$i,$year)); // outputs day eg 01,13,23 etc

    $dates[$month][$wk][$wkDay] = $day;  // storing date in array 
    } 

return $dates; 
}

$dates = getDates(2014);

echo '<br/>'.$dates['01']['01']['Wed']; // getting 01
echo '<br/>'.$dates['01']['01']['Thu']; // 01 (should get 02 as it is 2nd jan thu in 2014)
echo '<br/>'.$dates['01']['01']['Fri']; // 03

when i echo $day in for loop i m receiving 01 02 03 04 etc which is correct but when i echo same in $dates array above i am receiving 01 for both 1st month 1st week wednesday and 1st month 1st week thursday. Why? Where Am i wrong? All other dates i am receiving for 2014 calender is correct.

3

There are 3 answers

0
S.Pols On BEST ANSWER

@ymas is right. Because you are using 366 days in 2014, number 366 is the first day in 2015. This results that the first day of 2015 overwrite the value in your current array. Fix this by check the number of days in the year and use that value instead of the static 366. That will be something like this:

function getDates($year){

    $dates = array();

    $daysInYear = date("z", mktime(0,0,0,12,31,$year)) + 1;
    for($i = 1; $i <= $daysInYear; $i++){ 

        $month = date('m', mktime(0,0,0,1,$i,$year)); // outputs month 01 for jan etc
        $wk = date('W', mktime(0,0,0,1,$i,$year)); // this outputs 01 if 1st week etc  
        $wkDay = date('D', mktime(0,0,0,1,$i,$year)); //weekday eg mon ,sun etc
        echo $day = date('d', mktime(0,0,0,1,$i,$year)); // outputs day eg 01,13,23 etc
        $dates[$month][$wk][$wkDay] = $day;  // storing date in array 
    }
    return $dates; 
}

Note that you should not use 365 as static value because then 31 dec will not be available on leap year.

0
Glavić On

You are generating same timestamp 4x in the loop, which is overkill. Store timestamp in a variable, and then call date() function with that variable: see how.

Even better, faster and less memory consumption solution would be to use DateTime, like this:

function getDates($year) {
    $dt = new DateTime("$year-01-01");
    while ($year == $dt->format('Y')) {
        $dates[$dt->format('m')][$dt->format('W')][$dt->format('D')] = $dt->format('d');
        $dt->modify('+1 day');
    }
    return $dates;
}

demo

0
ymas On

I would recommend using the DateTime object for this:

    function newGetDates($year) {
        $start = new DateTime("$year-01-01");
        $end = new DateTime("$year-12-31 23:59");

        $period = new DatePeriod($start, new DateInterval('P1D'), $end);
        $dates = array();

        foreach($period as $day) {
            $dates[$day->format('m')][$day->format('W')][$day->format('D')] 
                = $day->format('d');
        }

        return $dates;
    }