Or: how what was supposed to be just a simple string parsing task escalated into computing planetary movements.
While working on the train station maps
for KDE Itinerary
I came across OSM’s
opening_hours tags on restaurants/shops/amenities/etc. Those contain a description for which
time intervals a given thing is available/open, in a machine-readable format.
Being able to evaluate this would be nice, as KDE Itinerary knows the time you are
going to be at a train station, so we can make the map more useful by focusing on elements that are actually
available while you are there.
OSM’s format is extensively documented, and also used by other systems that we use already (such as OpenTripPlanner) or that might become relevant for us in the future (such as ParkAPI). Another place where we encounter a similar (but simpler) format is schema.org annotations in websites that Plasma Browser Integration evaluates.
So, obviously we need this in a library we can use in all those cases.
Let’s look at a few examples of what OSM’s opening hours expressions can do, starting with the simple (and by far most common) case:
Mo-Fr 10:00-18:00; Sa 12:00-16:00
Localization aside this is still largely human-readable, and easy to evaluate with a bit of string parsing and QDateTime math.
Another common case is this slight variation:
Mo-Fr 09:00-15:00; PH off
PH stands for public holiday. That might look like a minor addition, but it moves from a bit of off-the-shelf date/time
math to knowing the public holidays at the location this expression applies to. Luckily there’s a framework for that already,
We now however also have to track additional context information for the expression, as they evaluate differently in different
Looking at the more rarely used features, there’s means to select the n-th weekday in a month for example (
Nov Tue[-1] - last Tuesday in November),
or periodicity on weeks (
week1-53/2 - any odd week), and many more such cases to express complex conditions. If this
reminds of the recurrence handling in iCal/KF5::CalendarCore,
it is very much like this.
To top it off, and to get to astronomical body movements, there’s also selectors for sunrise or twilight events. Those are computed based on the angular sun position at a given geographic coordinate at which the opening hours expression is evaluated. KF5::Holidays fortunately had most of this already, the missing bits have been added as part of this work.
So overall another nice reminder of what we all know to be the answer to “How hard can it be?” ;-)
Most of the above is implemented, some of the more rare details are still missing but at least can be added when needed.
There’s more however, namely the
SH (school holiday) selector. We currently have no comprehensive and world-wide
collection of school holiday data to implement this. Therefore expression containing this feature will raise an error.
Show me the code!
The code consists of a C++ library, QML bindings and a small QML demo application and can be found here.
To build and use this you also needs the very latest KF5::Holidays, all necessary extensions and improvements of that should be part of the upcoming KF 5.77 release though.