Need help mapping dates together

Hi,

I am working on a script that displays opening days of a restaurant for a full year.

I am generating 12 monthly calendars, starting with the current month. Each with it’s legend of month, weekday names and color coded weekends.

This part was easy and is already finished.

Now each cell (=day) of the calendars should get a different background color on open days.
Just by adding a respective class to the

.

The backend is a very simple MySQL database with a single table containing just startdate and enddate as timestamp.

My problem is, how to reference every day of the calendar to every set of dates in the database?

My first idea was, during generation to check the timestamp of each day against every possible “inbetween” from the MySQL-table.

While I am sure this would work in general, it seems like a lot of overhead and servertime at every time the script is called.

Is there a better - and less CPU-intensive - way to do this?
Some PHP date-funktion or maybe even a custom function that I don’t know of?

Any ideas are very much appreciated!

As you can see, I am new here, also english is not my first language.
So please be gentle :wink:
And if I did not make myself clear, just ask.

A helpful tip, show some code makes it easier for people helping you out.

Hopefully I am understanding you correctly, but I do something similar what you are describing -> here’s the portion of the script
[php] protected function checkForEntry() {

    $db = Database::getInstance();
    $pdo = $db->getConnection();
    $this->username = isset($_SESSION['user']) ? $_SESSION['user']->username : \NULL;
    if (!$this->username) {
        return \NULL;
    }
    $this->query = 'SELECT 1 FROM calendar WHERE date=:date AND created_by=:created_by';

    $this->stmt = $pdo->prepare($this->query);

    $this->stmt->execute([':date' => $this->urlDate, ':created_by' => $this->username]);

    $this->result = $this->stmt->fetch();

    /* If result is true there is data in day, otherwise no data */
    if ($this->result) {
        return "memo";
    } else {
        return \NULL;
    }
}

/* Current Month's Calendar days */
protected function currentMonth($date) {
    $this->isHoliday = new Holiday;

    /* Grab the current month DateTime */
    $this->current = new DateTime($date);

    $this->days = $this->current->format('t'); // Days in the current month:		
    /* Generate each day of the week's date */
    for ($x = 1; $x <= $this->days; $x++) {
        if ($x < 10) {
            $this->urlDate = $this->current->format('Y') . '-' . $this->current->format('m') . '-0' . $x;
        } else {
            $this->urlDate = $this->current->format('Y') . '-' . $this->current->format('m') . '-' . $x;
        }

        $this->memo = $this->checkForEntry();  // Highlight day if there's data in that particular date:
        if ($this->isHoliday->checkForHoliday($this->urlDate)) {
            /* Grab the important date(s) of the month and put it into an array */
            $this->highlightHoliday = 'highlightHoliday';
        } else {
            $this->highlightHoliday = \NULL;
        }
        $this->sendDate = new DateTime($this->urlDate);
        /* Figure out if the month's day is today and highlight if it is */

        if ($this->today->format('Y-m-d') === ($this->urlDate)) {
            $this->highlightToday = 'highlightToday';
        } else {
            $this->highlightToday = \NULL;
        }
        /* The Actual Link of the day of the week for the current month */
        $this->calendar[] = '<li class="calday ' . $this->highlightHoliday . ' ' . $this->memo . '"><a class="mark ' . $this->highlightToday . '" href="calendar.php?urlDate=' . htmlspecialchars($this->sendDate->format('Y-m-d')) . '&amp;page=' . htmlspecialchars($_SESSION['page']) . '">' . $x . '</a></li>' . "\n";
    }
}[/php]

It only hightlights days that has data in that particular data by calling this method (function) $this->checkForEntry() and putting the value in $this->memo variable. Then I simply have it as a class and let CSS do it’s magic. :wink:

It’s not CPU intensive at all in my opinion and if I’m understanding you correctly you’re basically following the same kind of scripting be it for a different outcome. In summary you check for any data for that particular date as you are building the calendar and highlighting the date(s) using CSS based on if there is data for that particular date. (IF there is no data for the date then the class name is NULL thus no highlighting is done)

Doing it this way you don’t have to worry about having data in every date field and you can actually control where the user(s) should go to by either a new input form page or an edit form page.

First of all, big thanks!

Second, you seem to be a way better programmer than I am. To be honest, I can’t make head nor tail of your code. Do I need anything else to run it?
I am not using any database wrappers (if this is what you are using).

A “ready made” snippet would be very welcome of course. But most I was interested in the “correct and most efficient” way to do it.

Here is my code so far (database part not included yet). I took a snippet from the source still mentioned in the code and changed it around a bit.

It should run “out of the box”:

[php]

<?php // https://css-tricks.com/snippets/php/build-a-calendar-table/ $dstart = 1444867200; $dend = 1445904000; $this_month = mktime(); //echo mktime(0,0,0,8,1,2015) - mktime(0,0,0,7,1,2015) . "
"; for ($ml=0;$ml<12;$ml++) { $dateComponents = getdate($this_month); $month = $dateComponents['mon']; $year = $dateComponents['year']; echo "
"; echo build_calendar($month,$year,$dateArray,$dstart,$dend); //echo $this_month . "
" . $mon . " / " . $year; echo "
"; $this_month = $this_month + 2678400; } //echo build_calendar($month,$year,$dateArray,$dstart,$dend); function build_calendar($month,$year,$dateArray,$dstart,$dend) { // Create array containing abbreviations of days of week. $daysOfWeek = array('Mo','Di','Mi','Do','Fr','Sa','So'); // Create array containing monthnames in German. $monthsOfYear = array('','Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'); // What is the first day of the month in question? $firstDayOfMonth = mktime(0,0,0,$month,1,$year); // How many days does this month contain? $numberDays = date('t',$firstDayOfMonth); // Retrieve some information about the first day of the // month in question. $dateComponents = getdate($firstDayOfMonth); // What is the name of the month in question? $monthNumber = $dateComponents['mon']; //echo "monthNumber: " . $monthNumber; $monthName = $monthsOfYear[$monthNumber]; // What is the index value (0-6) of the first day of the // month in question. $dayOfWeek = $dateComponents['wday']; // Create the table tag opener and day headers $calendar = ""; $calendar .= "$monthName $year"; $calendar .= ""; // Create the calendar headers foreach($daysOfWeek as $day) { $calendar .= ""; } // Create the rest of the calendar // Initiate the day counter, starting with the 1st. $currentDay = 1; $calendar .= ""; // The variable $dayOfWeek is used to // ensure that the calendar // display consists of exactly 7 columns. if ($dayOfWeek > 0) { $dayOfWeek--; $calendar .= ""; } $month = str_pad($month, 2, "0", STR_PAD_LEFT); while ($currentDay <= $numberDays) { // Seventh column (Saturday) reached. Start a new row. if ($dayOfWeek == 7) { $dayOfWeek = 0; $calendar .= ""; } $currentDayRel = str_pad($currentDay, 2, "0", STR_PAD_LEFT); $date = "$year-$month-$currentDayRel"; $calendar .= ""; $calendar .= "' rel='$date'>" . $currentDay . ""; // Increment counters $currentDay++; $dayOfWeek++; } // Complete the row of the last week in month, if necessary if ($dayOfWeek != 7) { $remainingDays = 7 - $dayOfWeek; $calendar .= ""; } $calendar .= ""; $calendar .= "
$day
 
" . $tday . $tmonth . $tyear . "
" . $this_day . "
" . $dstart . "->" . $this_day . "<-" . $dend . "
 
"; return $calendar; } ?>

[/php]

Code for a grid layout will also be added later, this is jut for testing purposes.

Does your script still apply to it and how would I get it to run?

Big thanks again!

Edit: Just noticed your signature about PDO. Will check it out now :wink:

2nd Edit: PDO extension was already enabled
When I run your code, the first statement already gives an error:

Parse error: syntax error, unexpected T_PROTECTED in C:\wamp\www\drittehand\phphelp.php on line 4

I removed the “protected” and the next thing it gives me is:

Parse error: syntax error, unexpected '[', expecting ')' in C:\wamp\www\drittehand\phphelp.php on line 16

which is:

[php]$this->stmt->execute([’:date’ => $this->urlDate, ‘:created_by’ => $this->username]);[/php]

Sorry to be such a pain, but as I said, your code is a bit above me …
btw., I am running PHP 5.3.13 and MySQL 5.5.24 on Wampserver

Today I wrote a simple database, containing only start- and enddates.
The script reads those and writes them in an Array.

Upon generation of the calendar, a simple function checks them against the values in the array.
Works great, and at least on my local server, very fast as well.

Seems to do the trick.

Thanks for your help again!

Sponsor our Newsletter | Privacy Policy | Terms of Service