Time Zones, that thorn in our side

Wolox Engineering
Wolox
Published in
4 min readOct 29, 2015

At some point in their lives, every developer has to deal with the problem I call “leaving your backyard”. When you write code in your computer, you are working in a controlled environment. But the world is not governed by the same rules, and has a few reality checks ready for us that may cause several headaches.

Time zones are one of those harsh realities. Of course, if we’re talking about showing the date of a news piece that was published on, +/- a few hours, it’s not the end of the world. But there are situations where +/- one hour may cause major issues, such as duplicating a monetary transaction.

App Time vs Server Time vs Database Time vs Client Time vs …

The first thing we have to focus on is the fact that every factor involved in the use of our app has its own way of showing time. Not being aware of this is what often leads us on the wrong track.

We must stop and think about the factors we can actually control and on those that will allow us to scale the project in the future.

For those of us who develop apps under a Rails environment it is best to assume that, while we could be in control of the machine hosting the server, that option is not even available. Therefore, we should only take care of the dates stored in the app and in the database.

Related Post: Reprise: 4 More Tips to Deal with Time Zones

On the other hand, Rails, foreseeing these scenarios, stores ALL dates in the database in UTC time (+0000), converting dates to the app’s time zone later.

The only dates we should care about, and the only ones we should work on, are the ones on the application. Combining any of the other dates means moving into unknown grounds.

Rails Application Setup

We can, if we want to, set a time zone different from the default (UTC) on config/application.rb, under the config.time_zone setup (i.e.: config.time_zone = ‘Central Time (US &Canada)’). For each serialization of a queries’ tuple that we make on the database with a certain date, Rails will change it to the specific time zone on its own.

Needless to say, this option is useful only if our app is localized (is time-dependent).

Application Time/DateTime

A recurring error when working with time zones is not finding the correct way to request the time from the application. Instructions like Time.new, Time.now, Date.today or the to_time method assume the user is requesting server time. Therefore, if we make a habit of using them, and our specs are written in the same way, we will wrongly assume everything works perfectly, and we will run into issues once we are in a production environment, with real data.

In order to tell Rails we want a date set on the application’s time zone we previously set, we must use conclusive methods.

TimeWithZone is a class that will actually allow us to do this (ActiveSupport::TimeWithZone). And, within the existent simple forms used to create them, we have Time.zone.now/Time.zone.parse. Internally, Time.zone calls an instance of the ActiveSupport::TimeZone type, which stores the time zone we set as default, and request from it the current date or the date which we want to parse. We also have available Time.current, that will run a Time.zone.now internally or with the in_time_zone Time instance method, turning a Time into a TimeWithZone from the default time zone.

DateTime is basically a more accurate Time, and it has its own current also.

Application Date

While Date also has its own current set from our default time zone, we have to consider that Date does not have a Time associated to it, making it a clean date, which is clearly tied to the time zone it was requested from. The day will change depending on the location and time it is requested from.

See also: Asynchronous processing using SQS and Shoryuken

In most of the cases where you work with different time zones, this will translate into a migration to Time.

But if we choose Date and want to transform the instance into a Time, let’s remember that Date.today.to_time will return the server Time and Date.today.in_time_zone will return the application Time.

If you fancy discovering more about Time Zone, you can read Reprise: 4 More Tips to Deal with Time Zones. When you finish reading both posts, consider yourself an expert in the topic!

Posted by Gastón Ponti (gaston.ponti@wolox.com.ar)

www.wolox.com.ar

--

--