Storing open hours for a site in Postgres

Viewed 676

I am trying to store on Postgres site opening hours, after reading this link I managed to come up with this table

create table opening_hours 
 (
    store_id  int REFERENCES site (id) NOT NULL,
    day_of_the_week integer NOT NULL,
    open_time    time with time zone not NULL,
    close_time   time with time zone not NULL
);

I am having a problem now that some stores are open between 6 AM and 1 AM on the following day.

As the time field is limited to 24:00:00 I could add a new row to the same table for the remaining hours e.g:

store_id,day_of_the_week,open_time,close_time
1,0,'06:00:00','24:00:00'
1,1,'00:00:00','01:00:00'
1,1,'06:00:00','24:00:00'
...

But that just seems to be too convoluted.

Another solution is to create this table:

create table opening_hours 
 (
    store_id  int REFERENCES site (id) NOT NULL,
    day_of_the_week integer NOT NULL,
    open_time    time with time zone not NULL,
    operating_minutes   integer not NULL
);

and populate the table with such content:

store_id,day_of_the_week,open_time,operating_minutes
1,0,'06:00:00',500
1,1,'06:00:00',500
...

However, this query would make the query to determine if a store is now() open a bit more difficult as I would need to consider specific cases when querying, ultimately what I would like to query is:

select (localtime > open_time and localtime < close_time) from opening_hours oh  where store_id = 1 and day_of_the_week = date_part('dow', now())

Another thing that I was considering is that I am always storing data for every store no matter if they are open or not, but for some of the reports, I need to filter out the events within the time range defined on my table opening_hours.

I'm looking for advice on what would be the preferred way of storing this data into Postgres.

1 Answers

You can query for an open store with this logic:

where (open_time < close_time and localtime between open_time and close_time) or
      (open_time > close_time and localtime not between open_time and close_time)

This uses between and not between for simplicity. However, they may not handle the exact opening and closing times the way you want (are those specific times included or not?).

Related