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.
A 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.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
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.
- Use pytz for utc timezone
- Use pytz for US/Pacific timezone
- 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…
- How to change the naive type to the aware type
- How to change the aware type to the naive type
- 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.