LiveEn
LiveEn

Reputation: 3253

One month missing when generating a list of dates using date and mktime()

Im trying to generate a list of months along with the year and 1st date of the month.

I use the below code, but oddly February is missing and March is being repeated 2 times

Code

        for ($i = 1; $i <= 12; $i++):

        $year='2013';

        $month_numb = date($year.'-m-01', mktime(0,0,0,$i));

        echo $month_numb.'<br>';

        endfor;

Output

2013-01-01
2013-03-01
2013-03-01
2013-04-01
2013-05-01
2013-06-01
2013-07-01
2013-08-01
2013-09-01
2013-10-01
2013-11-01
2013-12-01

Can someone tell me why this is happening and how do i fix it?

Upvotes: 1

Views: 433

Answers (6)

Kami
Kami

Reputation: 19407

Today is the 30th Jan. Dates in Feburary go up to only 28 this year. mktime() uses today's date for values not supplied. Since 30th Feburary is invalid, mktime() rolls over to the next valid date - 01 March 2013.

Change your code

for ($i = 1; $i <= 12; $i++):
    $month_numb = date('Y-m-01', mktime(0,0,0,$i, 1, 2013));
    echo $month_numb.'<br>';
endfor;

The above assigns the day/year to the code and then translates it, rather than taking today's values.

Upvotes: 2

James Boutcher
James Boutcher

Reputation: 2613

When calling mktime(), the default day of the month is the current day of the month (in today's case, it's 30.) Since Feb 30 is actually March 2nd (most of the time), that's why mktime(0,0,0,2) will return the month of March.

Give the day of the month to mktime, mktime(0,0,0,$i,1).

Upvotes: 2

Bart Friederichs
Bart Friederichs

Reputation: 33521

The fifth parameter of mktime will be set to today's day: (from docs: ... int $day = date("j") ...), which is 30 (of January). 30th of February doesn't exist, so it goes to March.

You'll see it will work correctly the first of february.

Upvotes: 0

Jules
Jules

Reputation: 7223

This is because today it's the 30th. And there is no 30th of February. Tomorrow you will have the same issue with all months with 30 days only. And on Feb 1st, your problems will be gone again.

The fix, add the 5th parameter, don't let the day of month default to today's date:

$month_numb = date($year.'-m-01', mktime(0,0,0,$i, 1));

Upvotes: 0

hsz
hsz

Reputation: 152216

Isn't it better to do it without date and mktime ?

$year = 2013;
for ( $i = 1; $i <= 12; $i++ ) {
  $month_numb = $year . '-' . $i . '-01';
  echo $month_numb . '<br/>';
}

Upvotes: 1

John Conde
John Conde

Reputation: 219824

Use DateTime. It's simpler:

$datetime = new DateTime('2013-01-01');
for ($i = 1; $i <= 11; $i++)
{
    echo $datetime->format('Y-m-d') . "<br>\n";
    $datetime->modify('+1 month');
}

See it in action

Upvotes: 0

Related Questions