如何在数据库中存储业务时间以便在它打开时进行搜索?

时间:2017-08-10 13:22:31

标签: mysql database postgresql database-design

假设商店从8:00到23:00工作,我们使用time格式。那很简单。某种:

where NOW() > start and NOW() < end

但是如果商店工作到第二天凌晨1点怎么办?现在正好是23:00;那么23> 1.这不会起作用。

那么如何以正确的方式存储和搜索营业时间?也许在end字段中更好地存储差异,或者我甚至不知道......

UPD :如果您建议使用时间戳,那么我将如何在一年后找到这段时间,例如?我们需要将所有日期转换为一个?

我现在决定使用的唯一解决方案。

select * from times where 
    ('05:00:00' between opens::time and closes::time) or 
    (
        closes::time < opens::time and 
        '05:00:00' >= opens::time and 
        '05:00:00' > closes::time
    ) or
    (
        closes::time < opens::time and 
        opens::time > '05:00:00' and 
        closes::time > '05:00:00'
    ) and dow = 4

因此,对于13:00:00 - 04:00:00,当变量为:

时,我会得到结果
  • 05:00:00 - 没有结果
  • 12:00:00 - 没有结果
  • 00:00:00 - 1行
  • 01:00:00 - 1行
  • 18:00:00 - 1行

如果您有任何更好的想法,请分享

4 个答案:

答案 0 :(得分:1)

您应该使用 TIMESTAMP 作为开始和结束列的data_type。然后你可以使用NOW()&gt;开始和NOW()&lt;结束。它会正常工作。

答案 1 :(得分:1)

存储营业时间的唯一正确方法是使用iCalendar RRules和ExDates

将规则存储在表格中。使用图书馆(Postgres有一些)来生成即将到来的一年的开放时间。使用物化视图

这使您可以处理假期,每月最后一个星期四关闭等事情。

答案 2 :(得分:0)

它有点不清楚你在用什么语言。但这里有一些例子。如果格式为从服务器到示例C#的dateTime,则可以使用:start&gt; date1&amp;&amp;结束&lt; DATE2。

如果使用MySQL,请查看此帖子:MySQL "between" clause not inclusive?

答案 3 :(得分:0)

t=# create table shop(i int, opens time, closes time, dow int);
CREATE TABLE
t=# insert into shop select g+10,'11:00','23:00', g from generate_series(1,5,1) g;
INSERT 0 5
t=# insert into shop select 23,'12:00','13:00', 6;
INSERT 0 1

那么你的逻辑就可以了:

t=# select * from shop where now()::time between opens and closes and extract(dow from now())::int = dow;
 i  |  opens   |  closes  | dow
----+----------+----------+-----
 14 | 11:00:00 | 23:00:00 |   4
(1 row)

它在星期四的ATM上开放。

以及Satruday开启和未开启的示例:

t=# select * from shop where '2017-08-12 12:59'::time between opens and closes and extract(dow from '2017-08-12 12:59'::timestamp)::int = dow;
 i  |  opens   |  closes  | dow
----+----------+----------+-----
 23 | 12:00:00 | 13:00:00 |   6
(1 row)

Time: 0.240 ms
t=# select * from shop where '2017-08-12 13:01'::time between opens and closes and extract(dow from '2017-08-12 13:01'::timestamp)::int = dow;
 i | opens | closes | dow
---+-------+--------+-----
(0 rows)