Why it’s confusing? datetime and unix time (POSIX) in Python

Why it's confusing? datetime and unix time (POSIX) in Python

Datatime class object in Python is confusing for 2 reasons. There are object categories naive and aware those treated differently in the datetime module plus local time interpretation on your computer or server if you convert unix time to datetime class object and vice versa. In this article I’d like to explain what datetime module types (native and aware) are and how to interchange datetime class object and unix time (POSIX).

Here’s the official document for datetime module in Python3.

datetime-Basic date and time types

What are naive and aware objects in datetime module?

These are the definitions from the site for naive and aware types in datetime module.

naive object does not contain enough information to unambiguously locate itself relative to other date/time objects

A naive object does not have timezone information with it so it’s up to the program in the environment (local timezone) considers what timezone your computer or server is in. Need to be cautious what date and time will be taken when a datetime class object is generated.

For example, when I run now = datetime.datetime.now() on my computer it returns the datetime class object (that is UTC + 9) the corresponding to the local time without letting it know timezone by me. A naive object is up to the program what timezone the program’s environment is in.

An aware object can locate itself relative to other aware objects. An aware object represents a specific moment in time that is not open to interpretation.

As the name derives, an aware object knows its timezone and the offset from UTC with the timezone object of the datetime module. The datetime objects can have an optional attribute tzinfo that represent timezones with fixed offsets from UTC.

You can be free from considering interchange of timezone especially the program is run on various timezone. Because the datetime object is now timezone-aware in granularity. Let’s take a look at some examples for better understanding.

Convert naive datetime objects into unix time

datetime.now method returns the current local date and time, and datetime.utcnow method returns the current UTC date and time as a naive object. When you convert this object into unix time (POSIX) you need to be aware of timezone of the datetime and take different approaches to do.

It’s ahead of 9 hours from UTC here, so the datetime.now and datetime.fromtimestamp functions return UTC +9 offset datetime in nature. timestamp() function that was intoroduced in Python3.3 returns POSIX timestamp corresponding to the datetime object.

There is no method to obtain the POSIX timestamp directly from a naive datetime instance representing UTC time. So we have to use the calendar module or add tzinfo in the datetime object (make the object aware type) to call timestamp() function.

If you need a UTC unix time datetime object from the calculated timestamp you can call utcfromtimestamp method and it returns the UTC datetime corresponding to the POSIX timestamp without tz, which is the naive type. It does not have any timezone information with it.

This result implies that the owner or the program should be aware of what timezone the object is in. If the program is run in multiple timezone and in various environments it would be ideal to use aware datetime objects. Let’s see how it works.

Convert aware datetime objects into unix time

It’s time to play with aware datetime objects. Let’s call datetime.now method with tz. You can use datetime timezone class or the library pytz for the attribute tz. Pytz is the recommended library to use in the official Python document. I tested 3 cases to create the datetime class objects for aware type.

  1. Use pytz for utc timezone
  2. Use pytz for US/Pacific timezone
  3. Use timezone class for JST

For aware type object you can use timestamp() method to return POSIX timestamp.

Each datetime class object has now tzinfo. You don’t need to use the calendar module to get the corresponding POSIX timestamp.

>>> int(now.timestamp())
1600344700
>>> int(now_us.timestamp())
1600344700
>>> int(now_jp.timestamp())
1600344700

fromtimestamp method returned the local datetime corresponding to the timestamp without tzinfo while the same method returned the converted datetime from the tz’s timezone. If tz is not None, it must be an instance of a tzinfo subclass.

Here are some additional examples of…

  1. How to change the naive type to the aware type
  2. How to change the aware type to the naive type
  3. How to change the tz attribute for the different timezone

To wrap up it’s important to understand which naive or aware datetime object you’re using conciously and it would be better to use aware objects with tz attribuete as much as possible.

Leave a Reply

Your email address will not be published. Required fields are marked *