[Node.js] How we underestimated time zones.

Jan Vojáček
Storyous DEV
Published in
3 min readMar 7, 2018

In this post, we would like to share with you a story of how we screwed working with time in Node.js and caused ourselves a lot of problems. But first, let me introduce ourselves at least a bit. The solution we develop here at Storyous is a complete cloud-based platform with point-of-sale system for various types of gastronomic facilities such as restaurants, cafes and bars.

What happened?

A problem occurred when we changed the production environment for some of our Node.js apps. The operating system of our new cloud environment had set different time zone than we were expecting to have. This caused misbehaviour which led to a point when our sophisticated invoicing system generated hundreds of wrong invoices which we charged our customers for! This is pretty serious problem.

How did that happened?

Javascript Date object internally stores date as a point in time only in UTC time zone in form of milliseconds since beginning of unix epoch (01.01.1970). However, when constructing a new date, local time zone is taken into account and the Date object is just adjusted accordingly. So when you initialise a date from a string where you don't have a time zone specified, you have a problem. We were doing just that unfortunately, similarly as shown in a code snippet below.

Cause of the problem.

As you can see, the time difference here is 2 hours, which is exactly what caused our problems with invoices.

There were 3 major conceptual mistakes we made:

  1. Storing date in DB without time zone explicitly specified.
  2. Not handling zones in code.
  3. Not properly checking new environment settings.

How to handle time zones in code?

Fortunately, there are several ways how to properly and safely handle time zones in Node.js.

1. You can initiate a new date with a string specifying time zone explicitly.

Initiation of a Date object with time zone specified in the initiation string.

This has some drawbacks because of winter and summer time. You would have to manually handle changing the time zone difference exactly when the time difference is about to change. In our case from `+02:00` to `+01:00`. This is not very convenient and that's why i recommend the next solution.

2. You can use a library to handle time zones for you and create Date object correctly with the time you expect it to be.

There are many libraries that solve this problem. In the snippet below, you can see example usage of moment-timezone.js library to initiate Javascripts new Date object, however it has many other useful usages.

Initialization of a new date using moment.js.

Now, the date is as we expected and we did not even need to do anything because library had taken care of everything for us.

Conclusion.

Time-triggered event are hard to test and problems in this area are very easy to overlook.

Never use local time when storing dates.

Watch all aspects of your application very closely for some time when moving to new environment.

Expect unexpected!

--

--