End times

Like most (all?) desktops, elementary OS has a date & time widget. You click it and it shows calendar stuff. Mine currently looks like this:

The elementary OS date widget, showing the month and two events for the day

(The world clocks are not standard; that’s something else I’m working on, but I’ll write about that some other time).

It gets its data from the Evolution Data Server, the backend store for the Evolution groupware client (and others stuff). This thing has a bunch of backends for different kinds of servers or stores. Or could have, in theory, but doesn’t really have that many.

So via the elementary Calendar program, I connected to my Fastmail CalDAV calendars (a terrible experience because EDS doesn’t support any of the CalDAV discovery mechanisms, but that’s another story), and my events started appearing.

A list of events

For many of them though, they had broken end times. You can see it in the screenshot above. Much as the gym is good for me, I’m not quite at the point where I can do a twelve-hour workout, especially not on a weekday.

It took a couple of weeks of evenings to figure out what was going on. You can go and read the bug report against EDS yourself, but I’ll summarise here.

Generally, CalDAV events will have a start time (the DTSTART property), and either an explicit end time (DTEND), or a duration (DURATION) that can be added to the start time to compute the end time. The start and end times can optionally have an explicit time zone, which don’t have to match, but will if the end time is created from the start time.

Events can also have “recurrence rules” (the RRULE property, among others), which describe repeated events. A program can apply these rules to the “base” event to create new virtual events, say, one a week or whatever.

In the end, there was a bug in the recurrence rule expander inside EDS. The underlying library, libical, has a deliberate quirk that when you ask for the end time, if there isn’t one, but there is a start and duration, then it will create one for you.

Up in EDS, when its building the virtual event from the recurrence rule, it asks libical for the end time, but then uses a different method to explicitly find the DTEND property and from there, its time zone parameter. It resets the timestamp’s zone to UTC, and then uses the zone it finds to offset it into UTC properly. But if it doesn’t find the DTEND property, it will just abort with the zone reset to UTC. And of course it doesn’t find it, because it was synthesized, so all my end times end up being 11 hours out (as is my offset here currently here in Melbourne, Australia).

I tried for a while to make a simple reproduction but couldn’t, so ended up recompiling EDS with a silly patch just to test the theory. That patch was deemed to be the right thing by upstream and accepted (or at least, a slightly more modern equivalent as elementary, via Ubuntu LTS, is carrying quite an old version).

So now I’ve got a nice little patch, but I’m still having to rebuild the EDS packages with the patch included. I’ve filed a bug against the Ubuntu package which I hope, but doubt, will make it into an update.

Why doubt? Well. Right through the whole thing I’ve been wondering how this happens. It’s not just this bug, but also the whole process of adding new calendars, which don’t use the discovery mechanisms that have existed for years. We see similar things with desktop clients at Fastmail; they consistently do the wrong things, or lack polish or whatever. When I see bugs like this, I wonder how they could possibly have survived for so long and that makes me wonder if anyone is even seriously using this stuff? And then I wonder if maybe its just that everyone went to Gmail, and all the developers went and bought Macs, and there’s just so few people actually using desktop clients for serious works.

I have no data on this of course, and I did the same thing so I can’t blame anyone, but if its true I wonder if we can ever really pull it back.

But whatever. For now, I can read my schedule well enough, and that’s pretty good.