php – Calendar generation strange fail – Education Career Blog

I set out to generate a array containing a 12-month calendar starting on this (now) month. This is for a particular application, and requires special code, so I cannot use calendar libraries.

Here’s the code I have:

header('Content-type: text/plain');

$Cal1 = array();

$now = new fTimestamp('now');
$now = $now->modify('Y-m-1 00:00:00');

for ( $i = 0; $i < 12; $i++ ) {
 if ( $i > 1 ) {
  $then = $now->adjust("+$i months");
 }
 elseif ( $i == 1 ) {
  $then = $now->adjust("+1 month");
 }
 else {
  $then = $now;
 }
 $thisMonth = $then->format('F');
 $Cal1$thisMonth = array();
 $thisMonthDays = $then->format('t');
 for ( $j = 0; $j < $thisMonthDays; $j++ ) {
  if ( $i > 1 ) {
   $then = $then->adjust("+$i days");
  }
  elseif ( $i == 1 ) {
   $then = $then->adjust("+1 day");
  }
  $thisDate = $then->format('j');
  $thisDay = $then->format('l');
  $Cal1$thisMonth$thisDate = $thisDay;
 }
}

var_dump($Cal1);

This should generate an array of the form:

array {
    "Month_Name" => array {
        Day_Number => "Day_Name"
        etc...
    }
    etc...
}

The script outputs the right number of months, but not the right number of days… The full dump is quite lengthy, so I’ll only post October, February, and March:

array(12) {
  "October"=>
  array(1) {
    1=>
    string(6) "Friday"
  }
  "February"=>
  array(22) {
    5=>
    string(8) "Saturday"
    9=>
    string(9) "Wednesday"
    13=>
    string(6) "Sunday"
    17=>
    string(8) "Thursday"
    21=>
    string(6) "Monday"
    25=>
    string(6) "Friday"
    1=>
    string(7) "Tuesday"
    29=>
    string(7) "Tuesday"
    2=>
    string(8) "Saturday"
    6=>
    string(9) "Wednesday"
    10=>
    string(6) "Sunday"
    14=>
    string(8) "Thursday"
    18=>
    string(6) "Monday"
    22=>
    string(6) "Friday"
    26=>
    string(7) "Tuesday"
    30=>
    string(8) "Saturday"
    4=>
    string(9) "Wednesday"
    8=>
    string(6) "Sunday"
    12=>
    string(8) "Thursday"
    16=>
    string(6) "Monday"
    20=>
    string(6) "Friday"
    24=>
    string(7) "Tuesday"
  }
  "March"=>
  array(19) {
    6=>
    string(6) "Sunday"
    11=>
    string(6) "Friday"
    16=>
    string(9) "Wednesday"
    21=>
    string(6) "Monday"
    26=>
    string(8) "Saturday"
    31=>
    string(8) "Thursday"
    5=>
    string(8) "Thursday"
    10=>
    string(7) "Tuesday"
    15=>
    string(6) "Sunday"
    20=>
    string(6) "Friday"
    25=>
    string(9) "Wednesday"
    30=>
    string(6) "Monday"
    4=>
    string(6) "Monday"
    9=>
    string(8) "Saturday"
    14=>
    string(8) "Thursday"
    19=>
    string(7) "Tuesday"
    24=>
    string(6) "Sunday"
    29=>
    string(6) "Friday"
    3=>
    string(9) "Wednesday"
  }

Now, what’s the matter?

,

Doesn’t directly answer your question, but I’d do it a lot simpler like so:

$cursor = mktime(0, 0, 0, date('m'), 1);
$end = strtotime('+1 year', $cursor);

$out = array();

while ($cursor < $end) {
    $outdate('F', $cursor)date('j', $cursor) = date('l', $cursor);
    $cursor = strtotime('+1 day', $cursor);
}

var_dump($out);

To directly answer your question, you’re always adjusting $then relative to itself with increasingly bigger numbers, hence you’re skipping days and are getting funky numbers.

 for ( $j = 1; $j < $thisMonthDays; $j++ ) {
     $then = $then->adjust("+$i days");
 }
  1. $then is the 1st, you add 1 (first iteration)
  2. $then is the 2nd, you add 2 (second iteration)
  3. $then is the 4th, you add 3
  4. $then is the 7th, you add 4
  5. etc pp.

Leave a Comment