你会如何处理PHP/MySQL中的时间和午夜?
使用INT商店分钟或使用TIME类型字段?
考虑下面的SQL查询:
SELECT * FROM opening_hours
WHERE week_day = WEEKDAY(NOW()) + 1
AND open_hour =< date_format(now(),'%H:%i')
AND close_hour >= date_format(now(),'%H:%i')
Run Code Online (Sandbox Code Playgroud)
open_hour/ close_hourfields是TIME类型字段.
假设open_time是"18:00",close_time是"02:00",当前时间是"22:41".我们为close_time有一个单独的DB记录(因为它在午夜之后),但我们永远不会在结果中得到它,因为close_time"02:00"不大于当前时间,"22:41".
此外,如果当前时间是"01:00",我们将获得NEXT日值,因为工作日不匹配.
那么解决方案是什么?
您是否愿意将这些值存储在INT(分钟)中,以便php能够直接处理这些值而无需任何转换?
例如...
当前时间:
// w = Day of the week, H = 24-hour format, i = Minutes
$timearr = explode(':',date("w:H:i"));
$currenttime = ($timearr[0]) * 1440 + $timearr[1] * 60 + $timearr[2]
Run Code Online (Sandbox Code Playgroud)
在数据库中,存储的打开/关闭时间值以分钟为单位.
现在假设,当前时间是"太阳,01:00"(一周的第一天),执行上述转换此值为60; 并且周(星期六)的最后一天的开/关时间设置为"17:00"和"02:00"(实际上是星期日),存储在DB中为9660和10200(星期六,26:00) .在这种情况下,上面的查询将找不到我们需要的记录(星期六,17:00,02:00),因为我们可能没有任何open_time小于"02:00"(120).为了解决这个问题,我们将"Sun,01:00"转换为"星期六,25:00",将$ 7*1440(整周)添加到$ currenttime,结果为10140.然后DB查询如下:
SELECT open_time,clos_time FROM open_hours
WHERE (open_time <= $currenttime
AND close_time >= $currenttime)
OR (open_time <= $currenttime +10080
AND close_time >= $currenttime + 10080);
Run Code Online (Sandbox Code Playgroud)
或者什么是替代和更整洁的解决方案?
存储分钟(int(4) unsigned)是正确的方法。
但是,您应该存储自星期一上午 12 点以来的分钟
,而不是存储工作日 + 开始时间、结束时间(带偏移量) :-
Monday 18:00 = (1 - 1)*60 * 18 = 1080
Tuesday 02:00 = (2 - 1)*60 * 24 + (2 * 60) = 1560
...
// please take note shop could have different operating hour for each day
Run Code Online (Sandbox Code Playgroud)
因此,当前时间是星期二凌晨 1:30,即:-
// mysql expression
$expr = (weekday(current_timestamp)+1) * 1440 + (hour(current_timestamp)*60) + minute(current_timestamp)
Run Code Online (Sandbox Code Playgroud)
SQL:-
select ...
from opening_hours
where
open_time >= $expr and
close_time <= $expr;
Run Code Online (Sandbox Code Playgroud)