Lost in Time(zones)
Falsehoods programmers believe about time came out in 2012. Yet, almost 12 years later, programmers still struggle with these issues. Just a few days ago, I encountered another time-related issue on a website. In this post, I want to describe the symptoms of the issue, my interpretation of what likely went wrong, and some suggestions on how to fix this issue.
Background
Let's start of with a bit of information on the site, so that you can hopefully follow my story later.
The affected website is a pretty basic CRUD app for some business process. You can create a request to kick off the business process, check on your prior requests' status, and view the response once your request was processed. From this response, you can start other processes as well. Most of the process is automated, so you can expect a response to your request within a quarter hour, usually.
The site is hosted somewhere in Asia, so it is a couple of hours ahead of my local time zone. For me, it was early in the evening, while it was already past midnight in the site's local time zone.
Symptoms
I sent in my request, waited a bit and went to check on the results. First, I got a validation error, that the timeframe for which requests to show cannot be in the future. This should have been my first clue.
I changed the timeframe to my local today and searched for all requests in that timeframe. However, the result list came back empty.
What went wrong?
Now, I cannot say with certainty, what went wrong, but here is my best guess as to what happened:
- When the system creates a new request, it sets a creation timestamp in its local (Asian) timezone.
- On the search page, it also prepolates the date filter with the current date, again based on its local timezone.
- However, when validating the date filter (on the client side), it uses my computer's local timezone. Since I'm a few hours behind, the configured date filter is “tomorrow” in my timezone and therefore rejected by the validation.
- When evaluating the filter (back on the server), the system assumes the sent date is in its local timezone. Therefore, it doesn't find the request, as from the filters perspective, the request was created a day later.
That is, we ran afoul of falsehood 18 in the list:
- The server clock and the client clock will use the same time zone.
How to fix this?
Since the fundamental problem are the divergent timezones between the client and the server, any solution has to enforce some kind of synchronization. Here are a couple of ways to do this:
- The client-side date filter validation code could be changed to use the server's timezone when evaluating a date. Then it would accept the date as sent by the server and everything would be okay. One drawback here is that the client-side code and the server's timezone have to be kept in sync.
- Similarly, the validation code could be templated on the server.
- Alternatively, the validation could be moved to the server. However, this still could run into issues such as the server's timezone changing between creating a request and looking it up (see falsehoods 9 & 10).
- The creation timestamp and date filter can be stored and transmitted as timezone-aware (alternatively UTC) timestamps.
While the issue may seem obvious in hindsight, I believe that anyone who hasn't been bit by it before (and many who were) would have known to avoid it. Similarly, while it's technically possible to test for this, no one would do so, unless a similar issue has come up before.
If you have any comments or feedback on this post, or just would like to ask a question, shoot me an email at korrat@proton.me.