I have created a php calender which will show one week at a time.Here is the code i have created
<?php
$week = date("W");
$year = (isset($_GET['year']))?$_GET['year']:date("Y");
$week = (isset($_GET['week']))?$_GET['week']:Date('W');
if($week>53){
$year+= 1;
$week=1;
}
?>
Next Week <!--Next week-->
Pre Week <!--Previous week-->
<table border="1px">
<tr>
<td>Employee</td>
<?php
for($day=1; $day<=7; $day++)
{
$d = strtotime($year."W".$week.$day);
echo "<td>".date('l',$d )."<br>";
echo date('d M',$d)."</td>";
}
?>
</tr>
when i am trying to go to the next week it is working correctly. But when the year is changing it is not working for the next year.
Leave the week calculation to the DateTime::setIsoDate() method.
Here is the simplest and best solution for your problem :
<?php
$dt = new DateTime;
if (isset($_GET['year']) && isset($_GET['week'])) {
$dt->setISODate($_GET['year'], $_GET['week']);
} else {
$dt->setISODate($dt->format('o'), $dt->format('W'));
}
$year = $dt->format('o');
$week = $dt->format('W');
?>
Pre Week <!--Previous week-->
Next Week <!--Next week-->
<table>
<tr>
<td>Employee</td>
<?php
do {
echo "<td>" . $dt->format('l') . "<br>" . $dt->format('d M Y') . "</td>\n";
$dt->modify('+1 day');
} while ($week == $dt->format('W'));
?>
</tr>
</table>
When you're using strtotime, your week has to be two-digit. You have to prepend a zero, if the week is lower than 10 before the for loop.
if($week < 10) {
$week = '0'. $week;
}
for($day = 1; $day <= 7; $day++) {
Also, a year only has 52 weeks, the condition at the beginning should be.
if($week > 52) {
$year++;
$week = 1;
} elseif($week < 1) { // If you want the possibility to go back too
$year--;
$week = 52;
}
Full code:
<?php
$year = (isset($_GET['year'])) ? $_GET['year'] : date("Y");
$week = (isset($_GET['week'])) ? $_GET['week'] : date('W');
if($week > 52) {
$year++;
$week = 1;
} elseif($week < 1) {
$year--;
$week = 52;
}
?>
Next Week <!--Next week-->
Pre Week <!--Previous week-->
<table border="1px">
<tr>
<td>Employee</td>
<?php
if($week < 10) {
$week = '0'. $week;
}
for($day= 1; $day <= 7; $day++) {
$d = strtotime($year ."W". $week . $day);
echo "<td>". date('l', $d) ."<br>". date('d M', $d) ."</td>";
}
?>
</tr>
</table>
Related
I'm creating a calendar with Sunday being the start of each week and I want to present the week number of the year before each row of dates.
This is my calendar
my calendar
How can I add week numbers like this:
This is what I need
My code:
<?php
function generate_calendar($month, $year) {
$calendar = array();
$days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$first_day_of_month = date('w', strtotime("$year-$month-01"));
$week_number = 1;
$week = array();
// Determine the week number offset
$days_from_january_1st = strtotime("$year-01-01");
$days_to_first_day_of_month = strtotime("$year-$month-01");
$week_number_offset = floor(($days_to_first_day_of_month - $days_from_january_1st) / 604800);
// Check if the last week of the previous month is full (7 days)
$last_week_of_previous_month = $week_number_offset;
if ($month > 1) {
$previous_month = $month - 1;
$previous_month_year = $year;
$previous_month_year = date("Y", strtotime("-1 month" , strtotime("$year-$month-01")));
$previous_month = date("n", strtotime("-1 month" , strtotime("$year-$month-01")));
if ($previous_month == 0) {
$previous_month = 12;
$previous_month_year = $year - 1;
}
$days_in_previous_month = cal_days_in_month(CAL_GREGORIAN, $previous_month, $previous_month_year);
$last_day_of_previous_month = date('w', strtotime("$previous_month_year-$previous_month-$days_in_previous_month"));
if ($last_day_of_previous_month == 6) {
$last_week_of_previous_month=$last_week_of_previous_month + 1;
} else {
// Check if the last week of the previous month only has a few days
$last_week_of_previous_month = $last_week_of_previous_month;
}
}
// Generate the previous month's days
for ($i = 1; $i <= $first_day_of_month; $i++) {
array_unshift($week, "");
}
// Generate the current month's days
for ($i = 1; $i <= $days_in_month; $i++) {
$week[] = $i;
if (count($week) == 7) {
$calendar[$week_number + $last_week_of_previous_month] = $week;
$week_number++;
$week = array();
}
}
// Generate the next month's days
$remaining_days = 7 - count($week);
for ($i = 1; $i <= $remaining_days; $i++) {
$week[] = '';
}
if (!empty($week)) {
$calendar[$week_number + $last_week_of_previous_month] = $week;
}
return $calendar;
}
$year = 2022;
echo "<table>\n";
echo " <tr>\n";
echo " <th colspan='3'>$year</th>\n";
echo " </tr>\n";
echo " <tr>\n";
for($i=1; $i<=12; $i++){
$month_name = date('F Y', strtotime("$year-$i-01"));
$calendar = generate_calendar($i, $year);
echo "<td>\n";
echo "<table>\n";
echo " <tr>\n";
echo " <th colspan='8'>$month_name</th>\n";
echo " </tr>\n";
echo " <tr>\n";
echo " <th>Week</th>\n";
echo " <th>Sun</th>\n";
echo " <th>Mon</th>\n";
echo " <th>Tue</th>\n";
echo " <th>Wed</th>\n";
echo " <th>Thu</th>\n";
echo " <th>Fri</th>\n";
echo " <th>Sat</th>\n";
echo " </tr>\n";
foreach ($calendar as $week_number => $week) {
echo " <tr>\n";
echo " <td>$week_number</td>\n";
foreach ($week as $day) {
if (empty($day)) {
echo " <td></td>\n";
} else {
echo " <td>$day</td>\n";
}
}
echo " </tr>\n";
}
echo "</table>\n";
echo "</td>\n";
if($i==3 || $i==6 || $i==9){
echo " </tr>\n";
echo " <tr>\n";
}
}
echo " </tr>\n";
echo "</table>\n";
?>
Trying to add week number which counts from first week of January (if last week of previous month is not full 7 days then first week of current month start from last week of previous month), but my code only count from first week of current month.
I managed to get the right result (as far as I tested) with IntlCalendar and its FIELD_WEEK_OF_YEAR constant instead of counting Sundays.
I did some refactoring of your function, but ran out of time to do a full reduction of the script (there may still be lines that can be simplified/condensed).
Code: (Demo)
function generate_calendar(int $month, int $year) {
$calendar = [];
$week_number = (IntlCalendar::fromDateTime ("$year-$month-01"))->get(IntlCalendar::FIELD_WEEK_OF_YEAR);
$month_start = new DateTime("$year-$month-01");
// Generate the previous month's days
if ($first_day = $month_start->format('w')) {
$week = array_fill(1, $first_day, '');
}
// Generate the current month's days
$days_in_month = $month_start->format('t');
for ($i = 1; $i <= $days_in_month; $i++) {
$week[] = $i;
if (count($week) == 7) {
$calendar[$week_number] = $week;
$week_number++;
$week = [];
}
}
if ($week) {
// Generate empty days for the next month
$calendar[$week_number] = array_pad($week, 7, '');
}
return $calendar;
}
I don't believe there is any way to set the start day of the week in the standard library of PHP without manual calculation, but you can do it easily with the intl library (make sure the intl PHP extension is enabled):
$cal = IntlGregorianCalendar::createInstance();
// Set start of week to Sunday
$cal->setFirstDayOfWeek(IntlGregorianCalendar::DOW_SUNDAY);
// Get week number of the year for the current date
$weekOfYear = intval(IntlDateFormatter::formatObject($cal, 'w'));
// Advance to the next week
$cal->add(IntlGregorianCalendar::FIELD_WEEK_OF_YEAR, 1);
// ect...
How do I make this day light red. The other days are green. I've tried something like this but something is missing. Can someone help?
You'll understand what I want to do if you read the code below. I'm missing a part but I don't know what part. Please help me.
<table border="1">
<?php
date_default_timezone_set('Europe/Stockholm');
echo"<tr>";
$week_number = 21;
$year = 2018;
if($week_number < 10){
$week_number = "0".$week_number;
}
for($day=1; $day<=7; $day++)
{
$days[$day] = date('d', strtotime($year."W".$week_number.$day))."\n";
$daysnumber=$days[$day];
$today=date('d');
if ($daysnumber>=$today){
echo"<td bgcolor='red'>$daysnumber</td>" ;
}
else
{
if ($daysnumber<=$today){
echo"<td bgcolor='green'>$daysnumber</td>" ;
}
else
{
}
}}
?>
</table>
<table border="1">
<?php
date_default_timezone_set('Europe/Stockholm');
echo"<tr>";
$week_number = 21;
$year = 2018;
if($week_number < 10):
$week_number = "0".$week_number;
endif;
for($day = 1; $day <= 7; $day++):
$daysnumber = date('d', strtotime($year."W".$week_number.$day));
$today = date('d');
if($daysnumber == $today):
echo "<td bgcolor='red'>$daysnumber</td>";
else:
echo "<td bgcolor='green'>$daysnumber</td>" ;
endif;
endfor;
?>
</table>
You are makeing mistake here:
$days[$day] = date('d', strtotime($year."W".$week_number.$day))."\n";
\n added space in $days[$day] because of it not able to compare with
'22 ' == '22'
i'm creating a calendar in php, but i can't start it on the saturday, i mean i would like a table that begins on saturday and finishes the following friday. i'm stuck :(
echo "<table class='table tableDisplay".$currentMonthNumber." table-bordered '>";
echo "<tr>
<td>Saturday</td>
<td>Sunday</td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
</tr><tr>";
for ($i=1; $i <= $nbOfDaysInCurrentMonth ; $i++) {
$p = date('w', mktime(0,0,0, $calendrier_date_mois, $i, $calendrier_date_annee));
if($p == 5){
echo "</tr><tr>";
}
echo "<td>".$i."</td>";
}
echo "</table>";
You can use PHP's DateTime API. I have created a sample script for you below, where the script first checks if today is saturday, if not then it will use last saturday and then loops through 7 days.
<?php
$firstDay = null;
$isSaturday = (new DateTime("NOW"))->format('D') == 'Sat';
if($isSaturday) {
$firstDay = new DateTime("NOW");
} else {
$firstDay = new DateTime("last Saturday");
}
$days = 7;
for($i=0;$i<$days;$i++) {
echo $firstDay->format('Y-m-d').'<br />';
$firstDay->modify('+1 day');
}
Try this,
// Save for common reference
$today = strtotime('today');
// Get the first and last day of this month
$fdotm = strtotime('first day of this month', $today);
$ldotm = strtotime('last day of this month', $today);
// first cell (top left) of the calendar
$first = date('w', $fdotm) == 6? $fdotm: strtotime('last saturday', $fdotm);
// last cell (bottom right) of the calendar
$last = strtotime('next friday', $ldotm);
// Rendering
echo '<h2>', date('F Y', $today), '</h2>';
echo '<table>
<tr>
<th>SAT</th>
<th>SUN</th>
<th>MON</th>
<th>TUE</th>
<th>WED</th>
<th>THU</th>
<th>FRI</th>
</tr>';
for ($date = $first; $date <= $last; $date = strtotime('tomorrow', $date)){
if (date('w', $date) == 6) echo "\n<tr>\n";
$fmt = $date == $today? '<b>%s</b>': '%s';
echo '<td>', sprintf($fmt, date('j', $date)), "</td>\n";
if (date('w', $date) == 5) echo "</tr>";
}
echo "\n</table>";
Hope this helps.
I need to include a php calendar on the sidebar of my page.
I am using a snippet I found weeks ago, as I have used it before and it works fine. But this time, I have to add next and previous buttons to display the previous or next month...
My question is... do I need to modify the php that generates the current month?
this is what I have so far:
<table class="month">
<tr class="days">
<td>Mon</td>
<td>Tues</td>
<td>Wed</td>
<td>Thurs</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
<?php
$today = date("d"); // Current day
$month = date("m"); // Current month
$year = date("Y"); // Current year
$days = cal_days_in_month(CAL_GREGORIAN,$month,$year); // Days in current month
$lastmonth = date("t", mktime(0,0,0,$month-1,1,$year)); // Days in previous month
$start = date("N", mktime(0,0,0,$month,1,$year)); // Starting day of current month
$finish = date("N", mktime(0,0,0,$month,$days,$year)); // Finishing day of current month
$laststart = $start - 1; // Days of previous month in calander
$counter = 1;
$nextMonthCounter = 1;
if($start > 5){ $rows = 6; }else {$rows = 5; }
for($i = 1; $i <= $rows; $i++){
echo '<tr class="week">';
for($x = 1; $x <= 7; $x++){
if(($counter - $start) < 0){
$date = (($lastmonth - $laststart) + $counter);
$class = 'class="blur"';
}else if(($counter - $start) >= $days){
$date = ($nextMonthCounter);
$nextMonthCounter++;
$class = 'class="blur"';
}else {
$date = ($counter - $start + 1);
if($today == $counter - $start + 1){
$class = 'class="today"';
}
}
echo '<td '.$class.'><span class="dayWrap">'. $date . '</span></td>';
$counter++;
$class = '';
}
echo '</tr>';
}
?>
</table>
<div class="changeMonthLinks">
<a class="col-xs-12" href="">< Prev</a>
<a class="col-xs-12 aright" href="">Next ></a>
</div>
I just don't know how to proceed...or what do I need to add in the anchor tags :S
Any help will be appreciate it.
Thank you
Thank you!!
I've added $now for the param ?now in the url and I'm parsing it with strtotime to the variable $dtNow, all the date functions are extended and the links in the bottom are extended with ?now=$dtNow + 1 month and ?now=$dtNow - month
Here's the code
<?php
$now = '';
if(isset($_GET['now']))
$now = $_GET['now'];
$dtNow = strtotime($now);
if(!$dtNow)
{
$dtNow = time();
}
echo "<h1>Today is " . date('Y-m-d', $dtNow) . "</h1>";
?>
<table class="month">
<tr class="days">
<td>Mon</td>
<td>Tues</td>
<td>Wed</td>
<td>Thurs</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
<?php
$today = date("d", $dtNow); // Current day
$month = date("m", $dtNow); // Current month
$year = date("Y", $dtNow); // Current year
$days = cal_days_in_month(CAL_GREGORIAN,$month,$year); // Days in current month
$lastmonth = date("t", mktime(0,0,0,$month-1,1,$year)); // Days in previous month
$start = date("N", mktime(0,0,0,$month,1,$year)); // Starting day of current month
$finish = date("N", mktime(0,0,0,$month,$days,$year)); // Finishing day of current month
$laststart = $start - 1; // Days of previous month in calander
$counter = 1;
$nextMonthCounter = 1;
if($start > 5){ $rows = 6; }else {$rows = 5; }
for($i = 1; $i <= $rows; $i++){
echo '<tr class="week">';
for($x = 1; $x <= 7; $x++){
if(($counter - $start) < 0){
$date = (($lastmonth - $laststart) + $counter);
$class = 'class="blur"';
}else if(($counter - $start) >= $days){
$date = ($nextMonthCounter);
$nextMonthCounter++;
$class = 'class="blur"';
}else {
$date = ($counter - $start + 1);
if($today == $counter - $start + 1){
$class = 'class="today"';
}
}
echo '<td '.$class.'><span class="dayWrap">'. $date . '</span></td>';
$counter++;
$class = '';
}
echo '</tr>';
}
?>
</table>
<div class="changeMonthLinks">
<a class="col-xs-12" href="?now=<?php echo date('Y-m-d', $dtNow - 30*24*60*60); ?>">< Prev</a>
<a class="col-xs-12 aright" href="?now=<?php echo date('Y-m-d', $dtNow + 30*24*60*60); ?>">Next ></a>
</div>
I made a simple PHP script for generating calendar. It has rounded weeks (I mean if month starts on Friday it will generate it monday of that week), navigation, etc. Works great, but there is a bug in October. It draws last sunday of month twice. I use sundays as a singnal for new row so it makes
Example of my calendar
Example of calendar with October bug
And here the code (I'm not professional, I learned PHP on my own, with no books, just with google and PHP manual):
<?php
function getfirstday($month, $year)
{
$datestr = "01-$month-$year";
$day = date('N', strtotime($datestr));
return $day;
}
function getlastday($month, $year)
{
$datestr = cal_days_in_month(CAL_GREGORIAN, $month, $year)."-$month-$year";
$day = date('N', strtotime($datestr));
return $day;
}
//Don't care about this, I just want to have weekdays in my primary language
function getweekday($weekDay) {
$list = array();
$list['1'] = "Pondělí";
$list['2'] = "Úterý";
$list['3'] = "Středa";
$list['4'] = "Čtvrtek";
$list['5'] = "Pátek";
$list['6'] = "Sobota";
$list['7'] = "Neděle";
return $list[$weekDay];
}
//What month and year do we want to show?
//Ger it from URL or use current
$month = $_GET['month'];
if ($month == "") {
$month = date('m');
}
$year = $_GET['year'];
if ($year == "") {
$year = date('Y');
}
//Firts day of month
$startDayStr = "01-$month-$year";
//Some calculation to get interval of whole month and rounded weeks
$startDay = strtotime($startDayStr) - (getfirstday($month, $year ) - 1) * 24*60*60;
$roundMonth = 7 - getlastday($month, $year );
$limit = cal_days_in_month(CAL_GREGORIAN, $month, $year ) + (getfirstday($month, $year ) - 1) + $roundMonth;
//Some navigation
?>
<table>
<tr>
<?php
if ($month > 1) {
$prevm = $month - 1;
$prevh = "cal.php?month=$prevm&year=$year";
} elseif ($month == 1) {
$prevm = 12;
$prevy = $year -1;
$prevh = "cal.php?month=$prevm&year=$prevy";
}
if ($month < 12) {
$nextm = $month +1;
$nexth = "cal.php?month=$nextm&year=$year";
} elseif ($month == 12) {
$nextm = 1;
$nexty = $year +1;
$nexth = "cal.php?month=$nextm&year=$nexty";
}
?>
<td width="200" align="left"><Previous month</td>
<td width="190" align="center">
<?php echo date('m', strtotime("01-$month-$year 00:00:00")); ?>
</td>
<td width="200" align="right">Next month></td>
</tr>
</table>
<?php
//Let's generate our calendar
echo "<table border=\"1\"><tr>";
for($j=1;$j<=7;$j++){
echo "<td align=\"center\" width=\"85\" height=\"50\"><b>".getweekday($j)."</b></td>";
}
echo "</tr><tr>";
for($i = 1;$i <= $limit;$i++) {
$lastDayOfMonth = strtotime(cal_days_in_month(CAL_GREGORIAN, $month, $year)."-$month-$year 23:59:59");
$firstDayOfMonth = strtotime("01-$month-$year");
$weekDay = date('N', $startDay);
if ($startDay < $firstDayOfMonth || $startDay > $lastDayOfMonth) {
$class = "caltdb";
} else {
$class = "caltda";
}
echo "<td class=\"$class\" align=\"center\" height=\"40\">". date('d', $startDay) ."</td>";
if ($weekDay == '7') {
echo "</tr><tr>";
}
$startDay = $startDay + 24*60*60;
}
echo "</tr></table>";
?>
Could you help me fix this problem? I dont know why is it happening.
Thank you a lot,
Heretiiik
The problem is likely due to the fact that you're using + 24*60*60 to add one day to a timestamp. This causes problems with daylight saving time, because there are days with 23 or 25 hours when DST begins/ends.
Near the end of your script, replace:
$startDay = $startDay + 24*60*60;
with:
$startDay = strtotime('+1 day', $startDay);