Post

Contributing to GNOME, adjusting time zones in the import dialog

Contributing to GNOME, adjusting time zones in the import dialog

If I said in the last post that me and Felipe took the idea of working on only one issue at a time too seriously, in these last weeks we went even far (or better, less far): we stayed in the same issue we worked on in that post. However, this decision helped us to understand a lot about how the GNOME Calendar is structured and how the libraries work under the hood. Below, I describe in more detail our contributions and studies during this time.

More adjusts to the import dialog, #1243

Our MR !496 cited in the last post was merged with some few adjusts suggested by Georges, but it doesn’t completely close issue #1243: the import dialog now doesn’t break when importing files with encodings other than UTF-8 that have a byte-order-mask (BOM) in the beginning of it, however events being imported with virtual time zones are still being displayed with an incorrect time offset. To fix this problem, we decided to first study how Evolution’s Calendar handles VTIMEZONES and then understand how GNOME Calendar parses time zones read from files, so we would have in mind what we would need to change to achieve our goal. To clarify: RFC5545 defines the iCalendar data format, which is a standand for representing calendar data so it can be imported by different calendar apps; among the possible fields that can be defined, we can create artificial time zones, called VTIMEZONES, explicitly stating the offset from UTC (+00 time zone) we want to use for it.

Evolution is a personal information management application, offering among its capabilities a calendar service, whose back-end is used by GNOME Calendar for its purposes. Investigating the evolution-data-server repository at GNOME’s GitLab, we found that the virtual time zones that were not previously created or don’t corresponds to an existing real one are stored in a cache (an SQLite database), living apart from the events or the file which defines them. Now in memory, events can make references to it. This implementation is part of the back-end and certainly wouldn’t be part of the GNOME Calendar’s job, but gave to us some insights into how the data is handled at this level.

Back to GNOME Calendar, a level above of the one we were earlier, we decided to understand how the data is manipulated until get to be delivered to Evolution’s back-end. If Evolution is capable of handling with VTIMEZONES, there must be something wrong on this top level that affects the whole chain. After making some tests using files with different offsets for one virtual time zone, we observed something interesting: the import dialog would always display the event using the UTC time zone, but after importing it, the event in the month-view presented a different behavior, sometimes getting it right and sometimes not. The great discovery is that the Calendar is capable of handling virtual time zones! As one can see in its code base, the Calendar reads the time zones and imports them through calls to the Evolution back-end, and this explains why events were sometimes with the correct time: in the first import of the virtual time zone, a new entry in the Evolution cache is created; on the next ones, even if we change the offset, if we don’t change the TZID it’ll use the previous defined one (something already known). That is great! But and the import dialog?

Looking more closely to the import dialog, we observed that its logic handling events is different: as we are just seeing a preview of the event, we don’t want to already save the timezone in our cache, as we don’t know surely if it will be useful; so, the import dialog only creates a preview of the event, using a different logic and functions that aren’t used in the Calendar itself to deal with the events. The events are initially imported as ICalComponent structs and then converted to adequate structs that are effectively used, like the GDateTime one, which stores a complete date. To do this conversion, the util function gcal_date_time_from_icaltime (main/src/utils/gcal-date-time-utils.c) is used. To define the final date in this function, the time zone is determined using its associated location, that is, using the place in the world to which it refers. But, if we are using virtual time zones, which are artificial and not related to any physical place, we have a problem! The default behavior is to assign the UTC time zone, as we were seeing in our tests. To fix this, we submitted the MR !510, using now the raw offset from UTC to determine the time zone to be used in the final GDateTime that is returned by the function.

To make sure this behavior in the import dialog will persist, we also created an unit test for this util function: we proposed a new test file (test-utils.c) that will be useful to test the util functions, like this one we modified, and we already created the first test, using different real and virtual time zones to see if the behavior of the gcal_date_time_from_icaltime function is the one we expect. We would also like to create tests to check if the GDateTime created by this function matches the one used by the rest of the Calendar, but this looked to be something a little more complicated, as it would require us to manipulate the time zone caches as I described above. Certainly something for the future!

Next steps

We’ve been diving deep into the GNOME Calendar’s code over the past few weeks and our learnings have brought some light to what we are capable to do and what we’re not, considering the Calendar’s current structure. In this way, some next steps we want to consider for our future contributions are:

  • Both issues #1221 and #1110 are also related to the use of VTIMEZONES, but in their case the problem is with files that use time zones which are not defined anywhere. This is something that is worthy to look at, but requires more discussion as it’s not a simple fix, but a new behavior to be implemented.

  • The import dialog today set the UTC time zone to floating time events, which is incorrect by RFC5545, but it happens in this way because today the functions that are being used aren’t capable to differentiate floating time events from events without a time zone defined, which are expected to be UTC, as far as we know (requires more studies).

  • We still need to continue working on the test documentations, as pointed out in the last post. Felipe managed to fix his development environment, so now both computers can build the application, making it easier for us to split the tasks and work in parallel.

This post was made as part of the discipline MAC0456 - Tópicos Especiais em Engenharia de Software, BCC - IME - USP.

This post is licensed under CC BY 4.0 by the author.