I'm trying to find the best way to deal with restaurant opening hours. The complexity is due to the fact that:
A good approach seemed thus to register arrays of opened/closed times per each day of the week, in the format: seconds since the beginning of the week
. Here's an example
{
"address": "street 1, city, postcode",
"hours" : {
"mon" : [
{
"opened" : 25200, // 07:00
"closed" : 52200 // 14:30
}
],
"tue" : [
{
"opened" : 111600, // 07:00
"closed" : 138600 // 14:30
},
{
"opened" : 153000, // 18:30
"closed" : 180000 // 02:00 (of the day after)
}
],
...
}
}
(In the model I have a static variable rendered using a small piece of code I wrote to do the autoform dropdowns per each field)
In my view the opening hours for the whole week are rendered like so:
Monday: {{#each hours.mon}}
{{#if @index ">" 0}}<br />{{/if}} // this just breaks the second array item in a new line
{{getOpeningTime opened}} - {{getOpeningTime closed}}
{{/each}}
<br/>
Tuesday: ...
Where getOpeningTime
is a template helper that returns the time in a HH:mm format using moment.js
:
getOpeningTime: function(seconds) {
return moment().startOf('day').seconds(seconds).format('HH:mm');
}
So far all good - although I'm still not sure whether that's the right approach
Now, I'm trying to notice the user whether the restaurant is opened or not at the moment he/she's looking at the page. Here's what I wrote so far:
openedOrClosed: function() {
now = moment();
ddd = now.format('ddd').toLowerCase(); // I now I will look into the field hours.day - the first three letters all lowercase
day = now.day();
day = (day === 0 ? 7 : day); // This is just a conversion I do because I want to have Sunday at the end of the week
seconds = now.clone().diff(now.clone().startOf('day'), 'seconds') + (86400 * day) - 86400; // Minutes since midnight in Momentjs (http://stackoverflow.com/a/25390707/1435476) plus the sum of all the other days of the week to work out the global seconds since the beginning of the week
query = {};
query._id = this._id;
// here I have available all I need. but I'm not sure how to build the query
if (Restaurants.find(query).count() > 0) {
return "Opened";
} else {
return "Closed";
}
}
First of all: working with dates and time is a challenge :).
I think your 'seconds since the beginning of the week' format is not necessary. Momentjs can parse 'now' to day and hour (and more).
You should also account for exceptions like christmas etc. Besides that, a restaurant can be open multiple times a day (nine to two, and five to eleven for instance).
I would go for something like this:
restaurantname:{
//special days array of objects
specialdays:
[{date: date,
openinghours:
//again array of objects
[{start: sometime, end: sometime},
{start: somtime, end: sometime},
//etc
]
}]
},
normaldays: {mon: //openinghours like above, again array of objects with start and end, tue, wed etc}
After that you can check first: is it a special day? if yes => check if current time is after start and before end (loop over array of objects). Else if not a special day check the specific 'normal day' and do the same.
I think a switch would be ideal. You could start with specific to general, to make your condition fall through the specific cases first.
This is just an outline and I know it is challenging :).
Hope this helps...
Here you go,
var days = ['MakingIndex1ForMonday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
var query = {};
query._id = this._id;
query.dayName = days[now.day()];
if (Restaurants.find({
_id : query._id,
'hours.' + query.dayName.closed : {$lte : seconds},
'hours.' + query.dayName.opened : {$gte : seconds}
}).count() > 0) {
return "Opened";
} else {
return "Closed";
}
Queries i tried in mongoshell with your provided data,
so
is collection name here, 160000
& 190000
is the testing value in seconds here
this returns 1 row, as desired
db.so.find({'hours.tue.opened' : {$lte : 160000}, 'hours.tue.closed' : {$gte : 160000}})
this returns empty set aka 0 row, as desired
db.so.find({'hours.tue.opened' : {$lte : 190000}, 'hours.tue.closed' : {$gte : 190000}})
BTW i liked your implementation with seconds, it makes is very easier to manage. If you stuck again somewhere i will be here only
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With