Store Hours Widget

Hello friends,

I was hoping that I was at the point now that I would be answering questions in this group but alas, I have found myself stumped on what (I’m thinking) should be a fairly simple task. Hoping to get an experts eye on this to point out where I’m missing things.

The Outcome:
I’d like to dynamically display store hours based user configured settings. Users have a setting that contains open and closed hours for each day of the week (which is already working and handled elsewhere). Easy enough right? The kicker is, I’d like to take any days where the hours are the same and essentially eliminate them, so that instead of displaying: “Sunday: 8am-8pm, Monday 8am-8pm, Tuesday 8am-8pm, Wednesday 8am-8pm, Thursday 8am-8pm, Friday 8am-10pm, Saturday 8am-10pm” it would display “Sunday - Thursday 8am-8pm, Friday - Saturday 8am-10pm”.

Note
Since the hours are user configurable, this information is subject to change, meaning that it could be “Sunday - Tuesday 8am-8pm, Wednesday: 8am-9pm, Thursday - Saturday: 8am-10pm”for example or any combination thereof.

The Code
$days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
$hours = [ ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","10:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ];

for ($x = 0; $x < 6; $x++) {
$db = $x - 1;
if ($hours[$x][0] == $hours[$db][0] && $hours[$x][1] == $hours[$db][1]) {
// The hours are the same skip this
}
else {
// The hours don't match, add them to the list
}
}

The Summary
I know that the code above is overly simplified but I wanted to both save myself the embarrassment of showing some of the things I’ve been trying as well as get the point across without overcomplicating things.

Since the scope is confined to the 7 days a week, I suppose this could be done with a ton of conditionals accounting for every possible configuration but… that just wouldn’t make me feel good.

I’m wondering if there is either a library that has solved this or perhaps even some magical array manipulating function that could help out here?

Keep in mind that the hours and days of course can be manipulated any way needed to make this work since I’m pulling it in manually.

Thanks for any thoughts on how best to accomplish this!

<?PHP
$days = array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
$hours = array( "8:00 am,9:00 pm", "8:00 am,9:00 pm", "8:00 am,9:00 pm", "8:00 am,10:00 pm", "8:00 am,9:00 pm", "8:00 am,9:00 pm", "8:00 am,9:00 pm" );
$index = $hours[0];
for ($x=0; $x<=6; $x++) {
    if ($hours[$x] == $index) {
        // The hours are the same skip this
        if ($x==0) {
            echo $days[$x] . " " . $hours[$x] . "<br>";
        } else {
            echo $days[$x] . "<br>";
        }
    } else {
        // The hours don't match, add them to the list
        echo $days[$x] . $hours[$x] . "<br>";
    }
}
?>

Just use a database. All the logic needed to search and compare has already been written and tested. It’s called a database engine. All you have to do is store the data in a database table and use a query to find the information that matches the current day of week and time or just get all the information and display it as a schedule.

1 Like

Thanks @ErnieAlex,

This is super close but seems to miss some cases still. For example if I were to change the hours array to:
$hours = array("8:00 am,9:00 pm", "8:00 am,9:00 pm", "8:00 am,9:00 pm", "8:00 am,10:00 pm", "8:00 am,9:00 pm", "8:00 am,10:00 pm", "8:00 am,11:00 pm");

You’ll end up with:
Sunday 8:00 am,9:00 pm
Monday
Tuesday
Wednesday8:00 am,10:00 pm
Thursday
Friday8:00 am,10:00 pm
Saturday8:00 am,11:00 pm

In this case we don’t know what the hours are for Thursday.

Thanks so much for the thoughts here!

Hey @phdr,

Thanks for the comment! A couple things… undoubtedly on me for not doing a better job clarifying.

  1. All of the data is stored in a database… my struggle here is just gathering the data and presenting it. The arrays I used in the example code where just to provide a visualization of the data stored in the database.
  2. I’m not looking to display the current information…(e.g. “Today’s hours are:”) that would actually be fairly easy. My hope is to display the hours for the entire week but do so a little more efficiently than displaying every single day when it’s possible to say “Sun-Wed 8:00am-8:00pm”.

Finally, I guess more than anything I find myself more curious about solving “this” problem for education purposes. The stupid easy solution would just be to have the entire dataset stored as a simple string containing the information as I want it to be displayed.

So it’s not exactly that I’ve hit a brick wall on figuring this out “a way” to do this. Just assumed that I could figure out a better way to do it looping through the data that exists.

Thanks again for the comment!

Well, if it is already in a database, you can run a query, order by day and group by hours.
Then, display it as needed…

Or is it, group by hours THEN order by day???

Thanks @ErnieAlex,

I suppose the one kicker when it comes to the data storage is that open and closed are in separate rows in a key/value structure. So, for example, the key for Sunday’s Open is Sunday Open with a value of 8:00am and the key for Sunday’s Close hour is Sunday Close with a value of 9:00pm.

As with most situations, I’m working within the constraints of someone else’s architecture so don’t have complete control without significantly rewriting this functionality (i.e. not worth the effort).

I’m even worse in SQL than I am PHP but I’m not thinking that I could effectively group the keys since every key is unique?

Well, you just do a simple query comparing the three fields and order them by day and group them by the two open/close values. One small query…

Thanks again @ErnieAlex!

I’m really curious to understand what you have in mind for that? I’m not exactly sure what you mean by comparing the three fields.

Well, I would have to set up a table, but, loosely, off the top of my head…

SELECT day, WS_CONCAT(open, “-”, closed) AS the_hours FROM hours ORDER BY day GROUP BY the_hours;

So, it would query the table, I called “hours” and pull all days. It would combine the open and closed hours as “the_hours” which would give a listing like you had above. Then, group the open/close new filed and order by day… Something like that should work. Not tested as I do not have the database set up for it.

Thanks @ErnieAlex,

Cool idea. I wasn’t familiar with the CONCAT function so nice item to have in the tool belt.

I think your suggestion would work well enough if it weren’t for the way my data is structure in the database. If I’m following, it looks like I would need to have a fairly large and complex concatenation happening since the db structure looks like:

key               | value
Sunday Opens      |  8:00 am
Sunday Closes     |  8:00 pm
Monday Opens      |  8:00 am
Monday Closes     |  8:00 pm
Tuesday Opens     |  8:00 am
Tuesday Closes    |  8:00 pm
Wednesday Opens   |  8:00 am
Wednesday Closes  |  8:00 pm
Thursday Opens    |  8:00 am
Thursday Closes   |  8:00 pm
Friday Opens      |  8:00 am
Friday Closes     |  10:00 pm
Saturday Opens    |  8:00 am
Saturday Closes   |  10:00 pm

From what I can see, I would need to do one concatenation per day of week?

Well, first, in query languages, you can select the LEFT side of a field, or the RIGHT side. So, you can create a query to still process it. Or you could just read all the variables into an array and create some tricky code to sort it all out.

I am running out of time tonight, but, can drum up a query that should work for you in the morning.
Check back in about 12+ hours… Night!

You can also select from a field where a space is, like this:
SELECT LEFT(key,LOCATE(' ',key) - 1)
which will locate the day part out of your key for you. And, you would have to do the RIGHT part too
to get the Opens, Closes parts. The query would be more complex than the example I gave before.
But, almost the same! Later…

Very interesting! Going to have to do some research on that. Definitely extending my knowledge in SQL. In good news, I think I’ve got it figured out in PHP… as far as I can tell this works for every situation that I’ve tested.

$days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
$hours = [ ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","9:00 pm"], ["8:00 am","10:00 pm"], ["8:00 am","11:00 pm"], ];

$start = 0;
$end = 0;
$ticker = 0;
$count = 0;
$groups = [];

for ($x = 1; $x <= 7; $x++) {
    $db = $x - 1;
    if ($hours[$x][0] == $hours[$db][0] && $hours[$x][1] == $hours[$db][1]) {
        $ticker++;
        $end++; 
    }
    else {
        if ($ticker > 0) {
            $groups[$count] = [$days[$start],$days[$end], "hours" => ["open" => $hours[$start][0], "closed" => $hours[$start][1]]];
        } else {
            $groups[$count] = [$days[$start], "hours" => ["open" => $hours[$start][0], "closed" => $hours[$start][1]]];
        }
        $count++;
        $start = $x;
        $end = $x;
        $ticker = 0;
   }
}
return json_encode($groups);

This outputs:
[{"0":"Sunday","1":"Thursday","hours":{"open":"8:00 am","closed":"9:00 pm"}},{"0":"Friday","hours":{"open":"8:00 am","closed":"10:00 pm"}},{"0":"Saturday","hours":{"open":"8:00 am","closed":"11:00 pm"}}]

From here I can easily loop through the resulting array and present it! I’m a little concerned as to why I’m not getting an undefined offset error in the loop on the final cycle, but so far this is working.

Thank you very much @ErnieAlex for the excellent advice on this in the interim. I’ve definitely learned some useful SQL insights that will be helpful in the future.

Just heading to bed. glad you solved it. You can do a lot in queries that most people do not know about.
But, always nice to solve a programming puzzle… Goodnight!

Definitely! Thanks again for the inspiration and education on the journey!

Sponsor our Newsletter | Privacy Policy | Terms of Service