Working with dates, some things I learned so far.

Tim etc.
6 min readJul 17, 2019

When you start working with dates it doesn’t seem difficult. Then you will think, how the fuck do I get this time difference and how do time zones work? After a while you realized that you made some mistakes and encounter your first problems. If you read this article you will probably know what I am talking about. Because mistakes I have made. Some approaches give you nasty bugs that can be hard to solve afterwards.

Examples in this article are based on Angular in combination with Feathers, Sequelize and MySQL. I know it’s an uncommon stack, but you can apply the knowledge for other frameworks and libraries as well.

Don’t reinvent the wheel

There are many libraries available to help you handle dates, such as Luxon or Moment. These will give you a complete toolkit which makes your life a lot easier. This often includes parsing, calculations, transformations, duration and more.

Luxon is made by a contributor of Moment, probably the biggest date library out there, who used all of his experience and applied it to a blank canvas. The result is an API that is really easy to understand, well documented and great in combination with TypeScript. The best thing, it is immutable.

Create your own toolkit

Most likely you have some transformations that you use more often, make sure that you reuse them. This gets your team on the same page and makes sure all transformations are the same. One difference in a transformation can change the offset of your timezone, which results in a wrong date.

One way is to write a static class with all common transformations, on top of your Date library of choice of course.

Reusable collection of date transformations, just an example.

Don’t forget internationalization

Obviously the names of months should be translated, but don’t forget that the format of dates can be different as well. But don’t worry, most frameworks or additional libraries have something for internationalization. Angular has i18n built in, including support for the DatePipe. Using the predefined formats like ‘long’, ‘MediumDate’ and ‘ShortTime’ will handle all translations and formatting for you. Make sure you use these instead of hard coded formats like ‘M/d/yy’. Check the Angular DatePipe documentation for all predefined formats.

Are you ready for time zones?

The most valuable lesson I learned is to plan the usage of time zones. Create a solid architecture for it. Some things to keep in mind: try to keep one time zone per workspace (application/server/database), see where conversions take place and know how data is stored. Let’s walk through it!

Application

In your front-end application you want to use the local timezone. This makes it easy to understand for the user, otherwise it would be a bit confusing. Switching between time zones is not something you need in most scenario’s, so you can write all your code for the local timezone. That’s nice, easy and clean.

API-client

Next up, you probably have some kind of implementation for your API-client or a layer inside your application that is handling all the API-calls. That is the spot where you want to transform everything time related to UTC, before sending it to your server. This keeps your application from having any timezone changes.

API-server

Your data will begin it’s journey over the internet when it suddenly reaches your API-server. Which preferably runs in UTC. For the same reason as the application, you always use one timezone. In this case of course UTC instead of local time and it will always be UTC, even when you have users in multiple time zones or scale up to a distributed network (having servers in multiple time zones). This makes it a lot easier to manage and reduces time related bugs.

MySQL (data storage)

The final step, storage. In case you use MySQL you will need to know the following. MySQL will convert everything to UTC for storage and back from UTC to the current time zone when retrieved. Another reason why it is easier to have your server in UTC. More information about the DATE, DATETIME, and TIMESTAMP Types can be found in the documentation of MySQL.

Do you use something different? Lesson learned: do your homework on data fields. Look them up in the documentation, check how they are processed and their characteristics.

Alternatives

Of course it is possible to run your server in a timezone, plan this out properly. Try to keep time zones consistent within your workspace (ex. application/server/storage) so you will only have to deal with one timezone to prevent confusion and mistakes. Transform time zones only when needed and do this on entry/exit locations. This makes sure you don’t forget it somewhere, prevents a mix of time zones and it is easy to change later on.

More information about time zones

Want to know more about time zones and how to work with them? Time zones and offsets in the Luxon documentation is a great read, together with the referenced articles Time Zones Aren’t Offsets — Offsets Aren’t Time Zones and Stack Overflow’s timezone wiki page.

DATE vs. DATETIME (and TIMESTAMP)

Creating data structures, something I like doing. For dates and time, at least in MySQL, you can choose multiple types. DATE only stores the date and DATETIME as the name suggests time as well. TIMESTAMP only stores values from ‘1970–01–01 00:00:01’ to ‘2038–01–19 03:14:07’, if you need dates outside that range go for DATETIME.

Do you need a specific time? Go for DATETIME. Otherwise DATE is your way to go so you don’t have to manage time at all. Luxon will parse time though. My workaround is to only send the date back to the server and optionally set it to UTC while keeping the local time (to prevent the change of dates).

static dateSerialize(date: DateTime): string {
return date.setZone('utc', { keepLocalTime: true })
.toFormat('yyyy-MM-dd');
}

Using Sequelize?

The date types in Sequelize are a bit confusing, use ‘DATEONLY’ in your model for a MySQL ‘DATE’ column and ‘DATE’ will create a ‘DATETIME’ column in the database. I you thought that was weird…

Let’s get freaky!

Photo by yns plt on Unsplash

While doing some research on time zones I discovered some fun facts that I want to share with you. You’ll laugh when they don’t affect you, otherwise you will probably cry because they are hard to solve.

  • Time zones are managed by law and can be different per country or even state.
  • Time zones do not have to be hours, some country have an offset of 30 minutes.
  • Daylight Saving Time (DST) is for making better use of natural daylight by setting clocks forward one hour during the summer and back again for the winter. Some countries/states do this and some do not (it’s decided by law).
  • In the spring the clock is set one hour forward from 2 to 3 am for DST. The result, the time in between does not exist.
  • Later that year, also for DST, in fall the clock goes back one hour from 3 to 2 am. You guessed it, this beautiful piece of time happens twice.

That’s it, some fun scenario’s to wrap your head around. Especially calculating durations over DST, picking a time that does not exist or one that exists twice.

Thank you!

These where some things I learned and my thoughts how to solve them. I hope it helps. Do you have something to add or thoughts about approaches? Please let me know!

--

--