处理时间和午夜后

时间:2011-11-26 12:52:46

标签: php mysql sql

你会如何处理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')

open_hour / close_hour字段为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] 

在数据库中,存储的打开/关闭时间值以分钟为单位。

现在假设,当前时间是“太阳,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);

或者什么是替代和更整洁的解决方案?

3 个答案:

答案 0 :(得分:2)

存储分钟(int(4)unsigned)是要走的路 但是,不是存储工作日+ opening_hour,关闭小时(带偏移),而是 你应该在星期一上午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

因此,当前时间是星期二凌晨1:30,即: -

 // mysql expression
 $expr = (weekday(current_timestamp)+1) * 1440 + (hour(current_timestamp)*60) + minute(current_timestamp)

SQL: -

 select ... 
 from opening_hours
 where
 open_time  >= $expr and
 close_time <= $expr;

答案 1 :(得分:1)

SELECT open_time,close_time FROM open_hours 
    WHERE
         (open_time <= close_time AND
         open_time <= $currenttime AND
         close_time >= $currenttime)
         OR
         (open_time >= close_time AND
         ($currenttime <= close_time OR
         $currenttime >= open_time))

所以我在这里做的是,如果open_time大于close_time,那么它必须跨越午夜,在这种情况下,我检查以确保当前计时器大于开启时间,或者小于关闭时间,以确保下降在我们的时间跨度

开放时间------午夜-----关闭时间

如果开放时间小于关闭时间,那么我们知道午夜之间不会介入。因此,我们可以正常检查。

答案 2 :(得分:0)

我不知道你想做什么,但使用unix时间戳一直是我选择的正确答案。它更容易计算,无论时区如何,它总是正确的。

也许你应该研究那个