How to store office hours in PostgreSQL rows, so that I can calculate the office hours.
Example:
- We have open from 9:00 to 18:00 from Monday till Friday.
- Saturday we have open from 10:00 to 15:00
- from 24. Dec to 31. Dec we have open from 10:00 to 13:00 (but not on Saturday and Sunday)
- bank holidays like 25/26 December are closed.
- All above rules are valid until 31. Dec 2021.
- Starting from 01. January 2022 we have open from 10:00 to 18:00 from Monday till Friday. Saturday is open like before.
I would like to store this data in rows, so that we can develop an interface for it.
And then there needs to be a method which uses the rows/rules to calculate the specific opening hours.
Different timezone are not important in this context.
I use PostgreSQL version 12.6. But if needed I can upgrade to a newer version.
Best Answer
What you want to do is something like this (all the code below is available on the fiddle here):
I also did this:
You can experiment with
EXPLAIN (ANALYZE, BUFFERS)
and performance on your own H/W and S/W setup - see the fiddle.and for bank_holidays - some of which are variable (Easter for example):
And then you run the following SQL:
And to check the result, I had this query:
The idea behind this is to verify that the SQL is doing what I hope it's doing - so I check the "edge" cases - i.e. beginning of year, end of year, around Bank Holidays and over the Christmas period to New Year's Eve.
There are 55 records in the result set - I'll only show those around the New Year and the Christmas period:
A further check:
returns no records - as we would expect!
So, we can see that we have the appropriate hours for the appropriate days - i.e. weekday, 09:00 - 18:00, Saturday, 10:00 to 15:00 and nothing on Sunday. Bank Holidays and the Christmas period are also catered for. Obviously, you will choose Bank Holidays for Germany/Saxony.
Re. performance. I would encourage you to check your own system for performance - but if it's only a year, then I don't imagine that it's going to be a huge problem - but it's always worth bearing in mind as good practice.