Converting RFC3339 timestamp to UTC timestamp in Python

Pritish Mishra
4 min readSep 12, 2018

--

Problem Statement

Handling datetimes have become quite a common task during the code development journey of any developer. And, Python being one of the most popular languages, it won’t be surprising if this comes up fairly regularly as a requirement. I was also recently challenged with one such task. The task was pretty simple.

I was receiving a timestamp in RFC3339 format from an API endpoint. For similar responses, I was receiving timestamps in standard UTC format. So, in-order to keep things uniform, and to avoid the additional pain of handling a time-zone parameter, I had to convert the timestamp in RFC3339 format to one in UTC format.

Let me illustrate this with an example.

Suppose I have the timestamp in RFC3339 as “2018–09–07T04:57:58.050–07:00” and I want to parse it to somewhat like “2018–09–07T11:57:58.050”. How do we achieve this task?

Solution

I am going to showcase here, the final solution which worked for me. Then, we can discuss details regarding the same.

Now let us understand the solution code in little detail. First of all, we have used python libraries, iso8601 and pytz to solve this challenge. Why built-in functions of python couldn’t be used to achieve the same has been discussed in the next section.

In line number 3, we parse the date using the library iso8601. What it does is, it converts the timestamp passed in string format into a datetime.datetime Python object. This object also contains the time-zone information, which makes this step essential. The result of line number 3 looks somewhat like:

datetime.datetime(2018, 9, 7, 4, 57, 58, 50000, tzinfo=<FixedOffset '-07:00' datetime.timedelta(-1, 61200)>)

The catch is even after parsing the string into datetime object, we are still left with a timestamp which is still in the specific time-zone and not in UTC time. So, now we need to convert it to the UTC time, possibly utilizing the time-zone format information captured in the datetime object. That is exactly what the next line does. In line number 4, we parse the datetime object into UTC time using the library, pytz. We specify that the resultant time-zone we need to parse in, is UTC and thus, obtain the required timestamp.

Here, alternatively, if we had a requirement to parse the time-stamp to some other timezone format, e.g. Americas, we can also achieve the same here. We need to construct a tzinfo using timezone (adding the new timezone information), and then, pass the object as argument to astimezone function.

The _date_utc variable already contains the result in UTC format. The value of this variable looks somewhat like:

2018-09-07 11:57:58.050000+00:00

The last line is more of a cosmetic change. I had a requirement to construct the timestamp in the format like 2018–09–07T11:57:58Z.

So, we use the strftime function to provide the format to parse the timestamp into, and Voila!, we have the result in nice and structured UTC timestamp format.

Why was this problem slightly tricky to solve?

You may ask here: Was it that simple? Only 2–3 lines of code? So, why so much fuss about this?

So, let’s see, why it was tricky to solve this.

No built-in functions

One obvious question could be why we didn’t use a simple built-in function of python to solve this, like maybe, strptime. Yes, strptime is a very useful function to handle various timestamp formats. However, it is wickedly ignorant about any timezone information. It will work perfectly, for example, in this case:

ts = time.strptime('1985-04-12T23:20:50.52', '%Y-%m-%dT%H:%M:%S.%f')

However, it will fail to parse for a case as ours:

ts = time.strptime('1985-04-12T23:20:50.52+07:00', '%Y-%m-%dT%H:%M:%S.%f')

This conclusion was based on my online search. It could entirely possible, the Python community, huge as it is, has in-fact a built-in solution. Please suggest if you find such a solution.

Using a single library doesn’t solve the issue

As you may have noticed above, we have leveraged the functions of 2 different libraries to solve this problem. Thus, the solution looks a bit tacky. One obvious question could be, doesn’t any one of the libraries provide enough functionality to solve the issue?

The answer is ‘Maybe’! I tried to solve it using only one of the libraries, iso8601. However, although I was able to convert the string to the datetime object format with the necessary information captured, I was not able to use this information to get the timestamp in UTC format. Not sure, if there was any other way to achieve it somehow using only one function.

So, in conclusion, this was one of the challenges that I faced and solved, during the course of regular development, and thought to share my observations on the same. If you find the solution helpful, please show some love by clapping for it!

--

--

Pritish Mishra

Tech Enthusiast, Bibliophile, Software Developer, Active Researcher