Managing date and time in the programming world
It should be a piece of cake for many software developers, but it always surprises me how often date/time issues and misunderstandings how to handle them in computer software occur.
So, what are the common issues?
Forgetting about the Physics of Time
It’s kind of obvious, but still, you have to keep in your mind that:
At the exact moment when you are opening your bottle to celebrate your 01 Jan, somewhere else it is still sad 31 Dec. So, at the same moment, it is 31.12 for one user and 01.01 for another one. So one single event in your system is happening at the same moment for everyone but from the different “time view” of your users and systems (including your own server).
And this is the nature of time. None of your decisions in computer programming design change this simple fact.
While keeping in mind this and globalisation trends you have to design your systems properly and decide what “views” you would like to provide for your users.
Wrong data-types choices to store and handle dates
Let’s go to more practical advice.
If you store some time events with date/times attributes (e.g. for ‘created’, ‘modified’ fields in your data records) - use data-types with the ability to handle time zones.
Here we’re talking about many variations of data-types like: a simple UNIX time, ISO 8601 string with time zones, DATETIME/TIMESTAMP in databases, xsd:dateTime, LocalDateTime, ZonedDateTime in Java, etc.
The important thing here is — while processing your data don’t lose time zone information in your time events. You don’t need to convert it to any timezone, but you have to handle them correctly (storing/sending/receiving).
For instance, if you receive something like ‘01.01.2017 00:00:00 UTC+02’, you have the following possibilities:
- Store or send it ‘as is’ (with the timezone UTC +02).
In the case where you also need to restore the original event source time zone (a user time zone which had been used to create some event), you have to store an additional field or use the specialised data-types like ‘ TIMESTAMP WITH TIMEZONE’ in RDBMS. However, use the latest approach if you really need to know the original source timezone.
- Convert it to the server or configured timezone if you don’t need the source timezone information. It could be a UNIX timestamp (1483221600), or ISO 2601 string (‘2016–12–31T22:00:00Z’ or ‘2016–12–31T23:00:00+01:00'), LocalDateTime in Java, etc
What if you need to handle something like user birthdays. Many software developers use wrong data types for this case. You should not use timestamps or any other data types that could convert it to another timezone.
Unless we are talking about rare cases, generally you’re receiving birth dates like (‘01.01.1901’) to manage. The important thing is you usually don’t know what time zone it was is in. Many users (and systems) implicitly define this time zone like ‘an unknown time zone’ — the place where this event happened (a user was born).
What we’re discussing here are cases where time zones of events are implicitly defined (in our mind or in some context) and you have to avoid data-types with time zone conversions (like timestamps, UNIX time, etc). The simple solution here — use ‘String’ or any other specialised data-types if they are available (e.g. ‘DATE’ in RDBMS).
Handling date/times in UI/UX
One more thing. You need to correctly handle date related information in your user interfaces.
The simple rules are:
- If you show some time information in your UI without any time zone references in it then use the user system time zone (don’t use your server timezone). The easiest way is to convert them in your ‘front-end’ right before showing on the user’s UI.
- If you create something worldwide, you have to provide an ability to choose Time Zones in the user settings and/or in your UI views.
Look at the example from Google :