We make a product which is used by all kinds of different companies. Some of those companies are small and just have a limited user base, while other companies are multinationals, with end-users all over the globe. Typically this means that you have many users from different time zones, all working together in the same environment.
Time zones. A dreaded word in the world of software. Even though most people take these for granted, the concept time zones can sometimes pose quite interesting challenges for us software engineers…
Works on my machine! Or does it?
One day, we received a call from a customer in Brazil, telling us that the Plan Board would crash when opened in a certain week. The Plan Board contains a planner which allows the user to assign tasks to people in an efficient way. When we got the call, initially we were a bit mystified by the bug. Our first thought was that perhaps the customer’s database got corrupted somehow, causing the crash. When we checked the data however, nothing seemed out of order.
Since corrupt data was ruled out, we started thinking that it could have something to do with time zones. We opened the Plan Board in our own time zone Amsterdam (UTC+1) and nothing happened. We then switched the time zone to São Paulo (UTC-3) and sure enough, the Plan Board crashed. Mind you, this only happened when it was opened in a specific week.
So what was causing the problem? Given that the crash only occurred in UTC-3, we were wondering what’s so special about that time zone? As it turned out, the week where the Plan Board kept crashing, was also the week where Brazil had its DST switch. We found the smoking gun, but it raised a new question: why didn’t the Plan Board crash in Amsterdam (UTC+1)? We have DST as well, but the Plan Board was working just fine in the week of our DST switch. Strange…
Small difference, big impact
The Plan Board makes extensive use of Joda Time, an open-source date and time library. Several calculations in the Plan Board were based on the assumption that a day starts at midnight, which by the face of it isn’t an unreasonable assumption to make. Well, we were wrong…
It turns out that Brazil’s DST switch happens exactly at midnight, which means that once a year, there is no midnight. Therefore, we didn’t have anything to base our calculations on, causing the Plan Board to crash. Well there’s your problem!
The actual bug was caused by several calls to Joda Time’s LocalDate#toDateTimeAtMidnight() method, which would throw an exception if the date represented by LocalDate did not have a midnight. We fixed the code by using LocalDate#toDateTimeAtStartOfDay() instead. The original method was later deprecated and eventually removed from Joda Time’s API.
Next to the fix itself, we also added extensive unit and integration tests to verify that the product will always work, regardless of the time zone it’s viewed in. For instance, instead of only testing in UTC+1, we explicitly test in several different time zones as well. This way, we can be relatively sure that the bug (or similar bugs) won’t reoccur the next time there’s a DST change somewhere in the world.