Let’s say I’m maintaining a database of events, which could be anything from the weekly schedule of a business’s operating hours (Monday-Friday: 10AM-7PM, Sat: 12PM-6PM, Sun: Closed) to monthly events (Art fair, every first Saturday, from 10AM – 5PM) to an annual event (Christmas Eve charity dinner, 7PM-9PM)
In an ideal situation, I would like to query the database with any given day, say:
Thursday, Jan. 12, 2012, 12PM
…and find all events that are occurring on:
- a regular Thursday noon (such as a business being open)
- every second Thursday (an art fair)
- Jan. 12, specifically (er…Turkmenistan Memorial Day)
I suppose there’s no point in talking about the query construction without first thinking how such dates/times would be stored in a database.
I can’t think of how the concept of regular weekly operating hours (even ignoring edge cases) could be modeled in a one-record, single field that would also model a once-every-year event. At the very least, it seems like I would need at least five fields:
- Start-time
- Duration
- Day of the week (e.g. Mon. Tues., etc)
- optional absolute annual date (e.g. May 8)
- optional monthly occurrence (fourth Wednesdays)
And I’m guessing there’s no way to encapsulate this in a single row, right? For example, a business open every weekday would have five records.
And the end goal is to be able to do a relatively elegant query that could find all event-records which contain a given moment in their timeframe.
Not sure if you are asking specifically for a dbms-agnostic solution, anyway in postgresql (and I think it’s possible in most RDBMS) you can store Timestamps and get a lot of info out of them: http://www.postgresql.org/docs/8.4/interactive/functions-datetime.html.
Postgresql-specific answer
So for instance, to select events occurring each 2nd Thursday you could write:
To model duration you may simply have 2 timestamp fields, for the start/end of the event.
Also note that you can add or subtract timestamps, as well as know if intervals overlap.
In general, I would first try to use datatypes and functions provided by your DBMS, and only if you cannot really find a solution try to model it yourself.