views:

297

answers:

5

Hello, The code below is what I'm using for a website menu which moves the link for the current month's page to the top of the link list on the change of the month.

But this fails on the 31st of some months, such as April; I get two links to the same month for most of the links. I've read through the issues with the way php generates dates, but can't figure out how to change this code.

Anyone php Ph.D's want to take a stab at it? Thanks

<?php $month1 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+1 , date('d'), date('Y'))));
$month2 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+2 , date('d'), date('Y'))));
$month3 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+3 , date('d'), date('Y'))));
$month4 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+4 , date('d'), date('Y'))));
$month5 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+5 , date('d'), date('Y'))));
$month6 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+6 , date('d'), date('Y'))));
$month7 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+7 , date('d'), date('Y'))));
$month8 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+8 , date('d'), date('Y'))));
$month9 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+9 , date('d'), date('Y'))));
$month10 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+10 , date('d'), date('Y'))));
$month11 = (date('F', mktime(date('H'), date('i'), date('s'), date('m')+11 , date('d'), date('Y')))); ?>

<a href="http://mydomain.com/&lt;?php echo strtolower(date('F')); ?>/" title="<?php echo ucfirst(date('F')); ?>"><?php echo (date('F')); ?></a><br />

<a href="http://mydomain.com/&lt;?php echo strtolower($month1); ?>/" title="<?php echo $month1; ?>"><?php echo $month1; ?></a><br />

...(2 through 10)...

<a href="http://mydomain.com/&lt;?php echo strtolower($month11); ?>/" title="<?php echo $month11; ?>"><?php echo $month11; ?></a><br />
+4  A: 

You can look into using strtotime() instead of mktime. Since in strtotime() to can do

strtotime("-1 day", time());

On the 1st of some month and it will go back one day exactly. Even counting in leap years.

Ólafur Waage
A: 

Oh dear, that's some ugly code. You should really look into Loops (for/while/etc) and Arrays.

The code you have there could be reduced to this:

Edited: my code had the same problem as the original, fixed using scronide's solution, thanks for pointing it out.

<?php
for ($i = 0; $i < 12; $i++)
{
    $months[$i] = date('F', mktime(0, 0, 0, date('m') + $i, 1, date('Y')));
}

for ($i = 0; $i < 12; $i++)
{
    print '<a href="http://mydomain.com/'.strtolower($months[$i]).'/" title="'.$months[$i].'">'.$months[$i]."</a><br />\n";
}
?>

Or if you don't mind combining the two functions (getting the month names, and printing the links) together, and you don't need the month names stored for anything else:

<?php
for ($i = 0; $i < 12; $i++)
{
    $month = date('F', mktime(0, 0, 0, date('m') + $i, 1, date('Y')));
    print '<a href="http://mydomain.com/'.strtolower($month)."/\" title=\"$month\">$month</a><br />\n";
}
?>
Chad Birch
This also retains the problem of the original code: +$i month won't work for dates that don't exist in the next month.
scronide
Ah, you're right, if it's March 31 or some such, it will break. Will edit, thanks.
Chad Birch
Yup, it's ugly code. But I figured I'd ask one question at a time, and maybe someone would show me a better way.... Thanks for all the answers - Mark
songdogtech
A: 

I have no idea if this solves your problem, as I'm not really sure I understood what the problem was, but I have an idea on how you could make this code a bit more readable:

<?php 
    $month1 = date('F', strtotime("+1 month"));
    $month2 = date('F', strtotime("+2 month"));
    $month3 = date('F', strtotime("+3 month"));
    $month4 = date('F', strtotime("+4 month"));
    $month5 = date('F', strtotime("+5 month"));
    $month6 = date('F', strtotime("+6 month"));
    $month7 = date('F', strtotime("+7 month"));
    $month8 = date('F', strtotime("+8 month"));
    $month9 = date('F', strtotime("+9 month"));
    $month10 = date('F', strtotime("+10 month"));
    $month11 = date('F', strtotime("+11 month"));
?>

(but i also agree with Chad Birch's note about using loops instead of repeating the code)

<?php
    foreach(range(0,11) as $key){
        $months[$key]=date('F', strtotime("+{$key} month"));
    }
/* ... */
    foreach($months as $month){
        print "<a href='http://mydomain.com/".strtolower($month).
            "' title='".$month."'>".$month."</a><br />";
    }
?>
elzapp
+2  A: 

Use 1 instead of date('d') in your code; however, any time you see duplicated code, where only a number changes, you should be thinking about loops:

<?php
for ($i = 0; $i < 12; $i++) {
    $month = date('F', mktime(0, 0, 0, date('m') + $i, 1, date('Y')));
?>

    <a href="http://mydomain.com/&lt;?php echo strtolower($month); ?>" title="<?php echo $month; ?>"><?php echo $month; ?></a><br />

<?php
}
?>
scronide
+2  A: 
Eddy
This works great; other answers still fail on the 31st of the month. Thanks, Mark
songdogtech