How can I create a function that can figure out th

2019-09-14 06:47发布

问题:

I have a PHP calendar that lists all of the days of the month in a table. Before the first day of the month I have numbers from the prior month and after the last day of the month are the numbers of the days for the upcoming month.

Here's a photo of the Calendar as it currently looks. As you can see the bottom gray numbers are working fine, but the numbers preceding the first day of the month are negative numbers and should instead appear as '29,30'

The numbers after the last day of the month were simply '32,33,34' for example, so I just created an if statement that checks if the number is greater than the total numbers of days in the current month and if so, then subtract the total numbers of days in the month from '32' for example, which would then make it appear as '1,2,3'.

if ($day > $total_days_of_current_month) {
  echo '<td>' . ($day - $total_days_of_current_month) . ' </td>'; // for example,33-31=2
}

My problem is creating an if statement that somehow knows what the last days of the prior month was. The problem is that some months have 30 days and some have 31 days. Also, the month of February and leap years are a problem. Does anyone know an if statement so i can make it appear as '28,29,30' from the previous month?

回答1:

Assuming $day is a UNIX timestamp:

// gets you the first of the month
$date = getdate(mktime(0, 0, 0, date('n', $day), 1, date('Y', $day)));

From here, do one of these:

$lastDayOfPrevMonth = strtotime('-1 day', $date[0]);

// or, better, get the first day "in the grid" (assuming week starts on Sunday)
$date = strtotime("-$date[wday] days", $date[0]);

I don't want to harp on it, but have you looked at my previous answer? That's a more robust way to build a calendar instead of all this special case checking.



回答2:

Perhaps this can help?

cal_days_in_month()

(Edited to include inshalla's feedback)



回答3:

Why not just take the timestamp of the first day of the month, and subtract 24 hours from it and then use date('d', $timestamp); ? Also, if you have a timestamp in that month, date('t', $timestamp); will get the number of days in the month for you.

A quick example:

// sets to 3am, first day of month, 3am helps us avoid DST issues with subtracting hours    
$monthStart = mktime(3,0,0,date('n'),1,date('Y')); 
$thisMonth = date('n', $monthStart);

// rewind to the sunday before- date('w') is the "weekday" 0 based    
$date = $monthStart - (date('w',$monthStart) * 60 * 60 * 24);     

while ($date<$monthStart || date('n', $date) == $thisMonth)
{
  echo "<tr>";
  for ($x=0; $x<7; $x++) {
    echo "<td";
    if (date('n', $date) != $thisMonth) echo " class='notMonth'";
    echo ">";
    echo date("j", $date);
    echo "</td>";
    $date += 60*60*24;
  }
  echo "</tr>\n";
}


回答4:

Take a look at the source of PHP-Calender-Class Project:

http://code.google.com/p/php-calendar-class/

class source: http://code.google.com/p/php-calendar-class/source/browse/trunk/calendar.class.php

It may give you some insight on the problem.



回答5:

Using cal_days_in_month(), How about adding the following code:

if ($day < 1) {
  echo '<td>' . ($day + cal_days_in_month(
     CAL_GREGORIAN,date_format("n",
         date_add(date_create(),"P-1M")))) . ' </td>'; // for example,-1 + 30 = 29th
}

EDITED: Added the date_format function



回答6:

Wait a minute... your month name at the top is wrong! It says "August 2009", but the month has 30 days and the weekdays are right for September 2009!

You need to repair the current month first, before worrying about other months.