Using Dates Correctly in Applications
Introduction
This is one of the topics that is not very common. Even though we are always interacting with Dates and Times in our application, they can be very complex depending on your use case.
Our entire application broke because of some DateTime concepts that wasn’t properly though through so ideally, I am writing an article about it so you can learn from my mistakes.
What are we talking about?
I see people bragging on how they use and developed highly scalable applications in a Microservices and Multi Region environment. While there’s nothing wrong with presenting the best version of yourself or the most adequate to the job, you should always keep in mind that there’s always some tradeoffs to every choice you make.
If you’re on the Cloud, you may be saving dates and times from many different time zones which is pretty standard. We’re talking here about the common pitfalls and solutions to get along with this generic requirement.
The Problem
To put it simple, let’s say you’re implementing a very special messaging app. You have a client in Chicago (US) that wants to text another one in Paris (France). A single country can have multiple time zones like the US. Now how would the server operate and manage those dates? Sending a text at 1 AM in Chicago would be equivalent to a 8 AM text in Germany.
To spice things up, you should not trust any data from the client, so you would need the Server’s time instead of your User’s local time. You don’t want your users to tamper the dates as he pleases right?
You’re now thinking that you can just convert your local server time to the user’s country time and sending those. This might be good for most cases, but sadly not all of them. I will discuss those as we talk through.
The Generic Solution
If you know about UTC, you just doesn’t think too much about this. It is a standard and common practice to store and manipulates server dates and times in UTC. You most likely heard your team lead rejecting one of your PRs because you forgot this tiny conversion.
Solution Feedback
Yes, this solves our problem and is basically used almost everywhere. But is it actually the way to go every time? Sadly NO !
There’s one variable everyone keeps forgetting. It’s Daylight Saving Time
“Daylight saving time (DST) is the practice of setting the clocks forward one hour from standard time during the summer months and back again in the fall, in order to make better use of natural daylight.”
Time Zones like UTC, our most loved solution does not actually account of DST. Time Zones are based on the latitude and longitude so how would they know? Also, DST changes over time and is not fixed by no means.
If you have an application that predicts the stock market, storing stock value with it’s predicted date will be problematic. You’re predicting that some business value will be 5 in 10–1–2028–1:00:00. But what if the DST changes meanwhile?
Time Zones do change and you’re basically converting your dates prematurely assuming these things are static. You’re basically invalidating all of your values because of this without you knowing. It is like a time ticking bomb that you don’t know when it will trigger and how much damage will it cause.
There’s no golden rule for everything. So how should we prevent this problem in the first place?
The All In Solution
Let’s think this through. Our problem is the time zones that can change in the future. Very logically, we can also persist the “Date Added of the Date” if that makes sense. This attribute can help us track the Time Zones and DLS changes when projecting in the future. We would need to convert that manually which is feasible but not ideal !
Adding to that and for our final trump card, there’s actually a Time Zone Database. There’s multiple libraries implementing and using this type of DB.
A Time Zone DB contains code and data that represent the history of local time for many representative locations around the globe. What’s different is that you now may work with a Time Zone Entity and a Time Zone ID called IANA. This IANA will help you track and manage the cases were something changes. You can always use this ID to recreate the actual current local time in the future.
Just keep in mind that you will most likely need to keep some of those old attributes for filtering and querying across the DB. Keep in mind that this only covers future dates and conversions. We might argue that your Date object is now complexe, but that’s a tradeoff you would need to suffer if you want those benefits.