3

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/<?php echo strtolower(date('F')); ?>/" title="<?php echo ucfirst(date('F')); ?>"><?php echo (date('F')); ?></a><br />

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

...(2 through 10)...

<a href="http://mydomain.com/<?php echo strtolower($month11); ?>/" title="<?php echo $month11; ?>"><?php echo $month11; ?></a><br />
Joe Doyle
  • 6,363
  • 3
  • 42
  • 45
markratledge
  • 17,322
  • 12
  • 60
  • 106
  • 2
    Don't you look at this and ask yourself "there should be a better way to do this..."? Loops and arrays, kind sir, loops and arrays. – Paolo Bergantino Apr 17 '09 at 20:49
  • I figured there was a better way, but that I'd stay with one questions at a time. I'm still learning php and mostly know pretty static code for webpages.... – markratledge Apr 17 '09 at 21:19

5 Answers5

4

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
  • 68,817
  • 22
  • 142
  • 198
2

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/<?php echo strtolower($month); ?>" title="<?php echo $month; ?>"><?php echo $month; ?></a><br />

<?php
}
?>
scronide
  • 12,012
  • 3
  • 28
  • 33
2

<?php

$current_month = date('n');
$MONTHS = array();
for ($m=0; $m<12; $m++) {
  $display_month = $m + $current_month;
  $MONTHS[] = date('F',mktime(1,1,1,$display_month,1,date("Y")));
}
foreach ($MONTHS as $month) {
  echo "
    <a
      href=\"http://mydomain.com/".strtolower($month)."\"
      title=\"$month\">$month</a><br />";
}
?>

Eddy
  • 1,862
  • 12
  • 12
0

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
  • 73,098
  • 23
  • 151
  • 149
  • 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 Apr 17 '09 at 20:58
  • Ah, you're right, if it's March 31 or some such, it will break. Will edit, thanks. – Chad Birch Apr 17 '09 at 21:02
  • 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 – markratledge Apr 17 '09 at 21:20
0

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
  • 1,961
  • 4
  • 15
  • 22