Software Engineering 101: Time zones and Working with Dates
There are some things which every software engineer should know but unfortunately it is not taught in the schools. One of them is: Time Zones and Working with Dates.
Software Engineering 101 Series —
- Stuffing multiple values into a single 64bit value
- Time Zones and Working with Dates(you are here)
The most important thing in any app with a database is about getting the dates and timestamps right. You might not experience any problems when your app only caters single timezone, but if your app is used by people all around the world, you need to be very careful about getting the dates and timestamps right for your users who are in different time zones around the world.
There are 2 different types to mark an instant of time —
- Timestamp
- Datetime
Timestamp —
Epoch, also known as Unix timestamps, is the number of seconds (not milliseconds!) that have elapsed since January 1, 1970 at 00:00:00 GMT (1970–01–01 00:00:00 GMT).
You might be thinking why January 1, 1970 at 00:00:00 GMT is the starting point in computer systems. Well, I could explain why but it completely deviates from the context of our article. So, below links have all the details about “why”.
Another important thing is — Unix Epoch Common, But Not Dominant. There are many epochs which are used by various fields. If you are interested to know about them, follow the below link —
But the most crucial thing to remember is, it is gonna work only till January 09, 2038 03:14:07 GMT (2038–01–09 03:14:07 GMT). Why? Because in most of the systems Unix timestamps use signed 32-bit wide integer to represent the seconds. This is known as Year 2038 problem
Although default unix timestamps are signed 32-bit integers, programming languages like Java can return a timestamp with a 64-bit integers. But most of the softwares like MySQL still uses the signed 32-bit integers to represent timestamps and it will return 0 after 03:14:07 UTC on 19 January 2038.
More about this MySQL behaviour below —
But it won’t be a problem if you are using a 64-bit systems, because by the time 2038 year arrives, it will be shifted to signed 64-bit integer by major software providers. The problem will be with the embedded systems which use 32-bit systems like military, aviation etc. More about that below —
The problem you should be anticipating as a Software Engineer is when you want to work with or store a time after January 09, 2038 or before January 01, 1970.
This problem has been experienced by AOLServer in 2006:
In May 2006, reports surfaced of an early manifestation of the Y2038 problem in the AOLserver software. The software was designed with a kludge to handle a database request that should “never” time out. Rather than specifically handling this special case, the initial design simply specified an arbitrary time-out date in the future. The default configuration for the server specified that the request should time out after one billion seconds. One billion seconds (approximately 32 years) after 01:27:28 UTC on 13 May 2006 is beyond the 2038 cutoff date. Thus, after this time, the time-out calculation overflowed and returned a date that was actually in the past, causing the software to crash. When the problem was discovered, AOLServer operators had to edit the configuration file and set the time-out to a lower value.
Players of games or apps which are programmed to impose waiting periods are running into this problem when they attempt to work around the waiting period on devices which harbor the coding, by manually setting their devices to a date past 19 January 2038, but are unable to do so, since a 32-bit Unix time format is being used.
Remember: Only use the timestamps if and only if you want to store the current date and time. Don’t use it to work on or to store future or past explicitly
DateTime —
Datetime is used to store the exact date and/or time, like a string. Unlike timestamp, which always stores in UTC, datetime has its own time zone. So, you need to be careful while storing a datetime.
Datetime can be in the form “YYYY-MM-DD” or “YYYY-MM-DD HH:MM:SS”. Though the name suggests it stores date and time together, you can store only the date also by making “HH:MM:SS” all zeros like — “YYYY-MM-DD 00:00:00”
As I already told you, datetime values are stored just like a string literals without any information about the time zone it belongs. For example, if you store the datetime in New York and then access it from Tokyo, then the datetime will represent the New York’s time zone, without any explicit info that it is a New York’s time zone. So, unless the person who is storing the datetime provides the time zone info, nobody can know about the time zone used to store it for sure.
Remember: Always store datetime in UTC! Never store it in your local or any other time zone
Always storing the datetime in UTC makes it very easy to reason and when you want to display it to your users, just convert from UTC to local time zone.
One more advantage of saving in UTC is — there is no confusion about Daylight Savings.
UTC/GMT/Zulu —
If you are not familiar with dealing time zones, you might be wondering what is UTC/GMT.
UTC stands for Universal Time Coordinated, and it’s the primary time standard by which the world regulates clocks and time. UTC use to be called Greenwich Mean Time (GMT), but still is in English speaking countries, or Zulu Time (Z), which is used in plane and ship navigation. UTC is the time at the Prime Meridian (0° Longitude) given in hours and minutes on a 24 hour clock.
To obtain your local time you need to subtract or add a certain number of hours from UTC depending on how many time zones you are away from Greenwich. The map below shows the standard difference from UTC time to local time.
To know more about the differences between UTC and GMT —
The main difference you should be knowing as a software engineer between GMT and UTC is that UTC does not observe Daylight Saving Time
Zulu Time —
You might have seen a datetime like 2020–12–31T20:17:46.384Z.
ISO 8601
This format is defined by the sensible practical standard, ISO 8601.
The T separates the date portion from the time-of-day portion. The Z on the end means UTC (that is, an offset-from-UTC of zero hours-minutes-seconds). The Z is pronounced “Zulu”.
Zulu time zone is used by military services which usually means UTC. You can find other list of time zones used by military services around the world below, if you are curious but we only deal with “Zulu”.
Choosing a Time zone for your servers —
This is a very important topic but most beginners don’t have enough knowledge.
Always! Always keep your server’s time in UTC
No matter in which time zone your server is in, always configure it to UTC. Because every software, program, programming language, logging systems etc like MySQL, MongoDB, Java, node(JavaScript) will return your server’s time when you ask for datetime or timestamp.
If you are having all your servers in a single time zone, then it doesn’t matter because you can infer about the default time zone based on your server’s region. But distributed servers across different regions will produce a lot of problems like out of order logs and data due to timestamps from different time zones and daylight savings.
Summary—
There is a famous rule while developing any program/software —
Never trust any data coming from the user! Not even from your grandma… Always sanitize user inputs!
Remember this even while storing info about date like when was the data created, posted or edited.
- Set all your servers’ time zone to UTC.
- Always use the Server’s time to fill up metadata like created, edited, posted etc.
- Always store the datetime in UTC time zone.
- While displaying the datetime to the user, convert it to their local time zone at the application layer.
- Never use timestamps to store past or future.
- Try to use datetime format instead of timestamps as it makes visual debugging easy. With timestamp, you have to convert from seconds to date but datetime is like a string. So, if you find yourself accessing the raw values for debugging, then try to use datetime.
Want to contact me? Twitter.com/@SkrewEverything.
Found any mistakes or got anything to say? Comment down below.
Liked it? 👏👏👏 it 50 times and Share it.
