简体   繁体   中英

mysql open hours past midnight

I'm building a api where i have a list of drinking bars that are open past midnight. I'm having problems finding out if they are currently open or closed.

Lets say for example that one of these bars has these opening hours:

Monday 
open time = 20:00
closed time = 05:00

Tuesday 
open time = 20:00
closed time = 04:00

If I want to know if a bar is currently open and the current time 04:00 (monday going on tuesday), this would result in that the current bar is closed because its tuesday and the closed time = 04:00

But what the actual result should be is that the bar is open until 05:00 (monday going on tuesday)

I have a list of 20+ bars where i need to know if they are currenly open or closed. Can this be accomplished in mysql or php? how should I setup my db table?

I have this as my current setup

Table Name : openhours Fields :

 id          int(11)
 bar_id      int(11)
 open_time   time
 close_time  time
 day         tinyint(1)

table records:

 id: 1
 bar_id: 1
 open_time: 20:00:00
 closed_time: 05:00:00
 day: 0

 id: 2
 bar_id: 1
 open_time: 20:00:00
 closed_time: 04:00:00
 day: 1

this query works fine for open days that dont go past midnight

SELECT `open_time`, `closed_time`, IF(CURTIME() BETWEEN `open_time` 
AND `closed_time`,'open','closed') AS `status` FROM `openhours` 
WHERE `day` = DATE_FORMAT(NOW(), '%w')

But how do i go about the past midnight issue?

it tried something like this but it is not quite right

  SELECT open_time, close_time, day, (CASE WHEN ((open_time <= close_time 
  AND open_time <= CURTIME() AND close_time >= CURTIME()) OR (open_time >= close_time 
  AND (CURTIME() <= close_time OR CURTIME() >= open_time))) THEN 'open' ELSE 'closed' 
  END) AS status FROM openhours WHERE bar_id = 2 and CASE WHEN (day = WEEKDAY(NOW())    
  AND (CURTIME() < open_time)) THEN CASE WHEN (day = (WEEKDAY(NOW()) - 1) 
  AND (CURTIME() < close_time)) THEN day = (WEEKDAY(NOW()) - 1) 
  ELSE day = WEEKDAY(NOW()) END ELSE day = WEEKDAY(NOW()) END

Thanks in advance!

You can use UNIX_TIMESTAMP() for this kind of issues:

SELECT `open_time`, `closed_time`, IF(UNIX_TIMESTAMP(CURTIME()) BETWEEN UNIX_TIMESTAMP(`open_time`) AND UNIX_TIMESTAMP(`closed_time`),'open','closed') AS `status` FROM `openhours` WHERE `day` = DATE_FORMAT(NOW(), '%w')

I hope I get your point :)

You want something like this

case closed < open
 not between open and closed
else 
 between open and closed 

When either return true, the bar is open

One option would be to store the seconds past the start of the week, that way you don't need to worry about midnight at all.

Add these to your table:

open_time_i   int(11)
closed_time_i int(11)

And make your data look like this:

id: 1
bar_id: 1
open_time: 20:00:00
open_time_i: 72000
closed_time: 05:00:00
closed_time_i: 104400
day: 0

id: 2
bar_id: 1
open_time: 20:00:00
open_time_i: 158400
closed_time: 04:00:00
closed_time_i: 187200
day: 1

Then your lookup could look like:

$seconds = time() - strtotime('this week last sunday', date("Y-m-d", time()))

SELECT `open_time`, `closed_time`, IF(
  $seconds BETWEEN `open_time_i` AND `closed_time_i`
    OR
  (("closed_time_i" >= 604800 AND $seconds BETWEEN 0 AND ("closed_time_i" - 604800)))
,'open','closed') AS `status` FROM `openhours`

The 2nd between statement checks if the bar was open past that change of week.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM