Understanding about RFC 3339 for Datetime and Timezone Formatting in Software Engineering
Small and simple things that not every engineer knows, but very important things that every engineer should understand.
A few days ago, when building the Mabar, we have a great debate about Datetime formatting. There’s an issue that our timezone is not consistent. So, later after a long fight and discussion, we come to an agreement to use a standard for our timezone.
We finally decide to use the RFC 3339 as the standard for the date-time format. Means, both backend and frontend will use this format to communicate about the DateTime format. And also, we agreed to use UTC+0 as the default timezone, even when creating the event and receiving the event detail from the server. And let both frontend and backend convert it based on their timezone.
So what is RFC 3339?
Introduction to RFC 3339
RFC stands for Request For Comment. RFC is a formal document from the Internet Engineering Task Force (IETF) that is the result of committee drafting and subsequent review by interested parties¹
There are already so many RFC documents released by this committee. And become standard in every business. One of their documents is the RFC 3339, a document for DateTime formatting. The link for the RFC 3339 can be accessed here: https://www.ietf.org/rfc/rfc3339.txt
Generally, if you look at the RFC document it mainly discusses about the DateTime formatting, and to summarize you will see how the proposed DateTime format like the example below.
Yap, just like that.
But there’s a question. For Datetime formatting, there’s already standardized by the ISO. It’s ISO 8601 standard for Datetime. And for people that already familiar with ISO 8601, the RFC 3339 is pretty similar. What’s different?
So, if you look again at the RFC document. RFC 3339 use/follow the ISO 8601 profile for the Internet DateTime. Clearly stated in chapter 5.6
So actually, there are no big differences between Date ISO 8601. The only small thing that makes these 2 different is the “T” syntax between date and time. ISO 8601 uses the “T” character to separate the date and time. In RFC 3339, you can replace the “T” character with only using space.
# This is acceptable in ISO 8601 and RFC 3339 (with T)
2019-10-12T07:20:50.52Z# This is only accepted in RFC 3339 (without T)
Just it. So overall, it still the same as the ISO 8601.
Understanding about Time Zone
I’m a bit shocked when I’m asking about RFC 3339 to around my close friend, there’s no one understand about this. Even for ISO 8601, it’s only a few of them who know the details about this.
Especially reading the TimeZone format. From 1–10 of my friend, I can say only 1 understand about the timezone format.
Take a look above examples. When I asked someone about it, they will say it is
2019–10–12 07:20:50.52 in Jakarta time, because we live in Jakarta. So he will assume it was Jakarta time. But that’s wrong. Because if we convert that time to Jakarta time it should be:
How is it possible? How do I can say that the Jakarta time of that example is should be
In RFC 3339, we can also know the time-zone from the format. It displayed in the “Z” syntax. “Z” means UTC+0. “Z” stands for Zulu timezone which is the same with GMT or UTC (https://stackoverflow.com/a/9706777/4075313). So if we put Z on the DateTime, it’s mean its timezone is UTC+0.
More detail example:
Look at the bold text. It will explain how the timezone is written in the DateTime format.
Why Is It Important?
This is really important to handle the request that comes from many timezones. If your application only accepts request as the same as your timezone (for now), then this might be not really treated well by the engineer.
And for the engineer, why is it really important even a few programming languages like Golang already handle this? It is because sometimes the engineer not understand it very well, and may come brings a new issue later.
Let me tell you a story.
So, I will tell an example why this is really important. This has just happened recently to me and my friend. We have an issue about transactions pending that we need to take a look at and verified.
In our application, we use UTC+0, and he(my friend) knows this. So to fix the transactions pending, I just need to get the details when the transaction occurred and check if there’s another transaction that pending around the pending one and re-validate all of the pending transaction at that time.
And here’s the problem, when I asked about the transaction time (created time) of the row in Database. He adds the hour automatically with our timezone which is UTC+7, but not change the timezone format. And it brings an extra time for me to verify all transactions of that time that should be intended to. Because I’m querying the wrong DateTime range.
#This is our datetime stored in DB
Then I asked him to tell the transaction time through chat. And he gives this to me.
# He add the hour with +7 but not change the timezone
So what’s wrong here? Look at the “hour” value. He added it with 7 and send it to me. But the timezone is still “Z” (UTC+0). Since I know to read the RFC 3339, I’m thinking this is UTC+0 because he wrote it “Z”.
And, with that date-time, I’m doing some queries to DB. But, what I got is not exactly what I want. And when I’m trying to query by the ID, it shows different than what he gives to me. I’m afraid there’s an update query to DB that causing it different than what he gives to me.
And it brings confusion to me. And to verify it, I ask him again, is it UTC+0 value or not, and he said, that he already added +7 to the hour. And I feel like arghhh…. 🤯
And then, I say to him, when adding the hour, please change the Timezone too. So it does not bring confusion to whoever will read the date-time.
So if we change the previous example to correct on with timezone UTC+7, it should be like this
#This is our datetime stored in DB
2019-10-12T07:20:50.52Z#This is how it should be converted to UTC+7
This is a really important thing for Engineers to understand the format to avoid inconsistency data. Luckily, from my experience above, it stills me who read the given date-time. What if there’s an application that will read the Datetime, then there will be so many inconsistency data, because we add manually and it’s the wrong timezone.
So here are the takeaways:
- “Z”: stands for Zero timezone (UTC+0). Or equal to +00:00 in the RFC 3339.
- RFC 3339 is following the ISO 8601 DateTime format. The only difference is RFC allows us to replace “T” with “space”.