Angular, timezones and Datetimepickers

Recently we developed an angular application for one of our Multinational clients with the purpose of helping them to manage accommodation, transfers and flight times. This app had to deal not only with dates but also time and we looked into many different date and time pickers created specifically for angular in order to deal with that. We ended up selecting angular-bootstrap-datetimepicker as our choice.

At first hand everything went fine but during development the daylight saving period started here in Ireland and we noticed the dates being stored in the server started to differ of what we were picking in the app by one hour.

Javascript is somewhat confusing in how it parses dates, times and timezones, even some browsers handle some things in different ways and what was happening was when the datepicker was parsing the date into a javascript object it was also adding local time information e.g. 19/05/2017 11:18:00 +1 hour instead of 19/05/2017 10:18:00, which was actually the “numbers” that were picked in the datepicker. When this information was being sent to the backend, the server was parsing this date object without timezone information so the date being stored in the server was one hour wrong.

We didn’t want the application to be timezone aware, we wanted the users to pick a date on the datepicker and store that date made of the “numbers” that were picked. No smart conversions or anything like that.

The datepicker already provided support to moment.js (which basically the whole world recommends it if you are dealing with dates in javascript) so all what we had to do was to ensure when we are setting dates using the picker the selected date was in UTC timezone.

In order to achieve this behavior we had to add moment-timezone which gave us support to deal with timezones and then changing the code of angular-bootstrap-datetimepicker in the following way:

On the datetimepicker.js file, on the function setTime, one line after case ‘moment’ we added moment.tz.setDefault(“Etc/UTC”) in order to enforce the timezone to UTC every time we are setting a date.

By telling the datepicker to use moment we started to have issues with the angular filter for dates, which simply stop working, so we added another library called angular-moment to deal with that. So the code for the input that shows the date ended being this:

  

Further action: Doing some more testing we discovered that by using moment.utc() we don’t really need add moment-timezone or do the setDefault(“Etc/UTC”) thing. We have not given this a huge amount of testing, but the code would look like this: