First, let’s show how the commonly-used plain datetime.datetime.now() gets the local time but does not have a timezone:
>>> import datetime >>> now = datetime.datetime.now() >>> type(now) <class 'datetime.datetime'> >>> now datetime.datetime(2024, 2, 17, 12, 47, 40, 34210) >>> print(now) 2024-02-17 12:47:40.034210 >>> now.tzinfo is None True >>>
Let’s add timezone to it, using the zoneinfo module that is in the Python standard library since version 3.9:
>>> import zoneinfo
>>> now = now.replace(tzinfo=zoneinfo.ZoneInfo("localtime"))
>>> now
datetime.datetime(2024, 2, 17, 12, 47, 40, 34210, tzinfo=zoneinfo.ZoneInfo(key='localtime'))
>>> print(now)
2024-02-17 12:47:40.034210+02:00
>>>
I’m in Europe/Helsinki timezone, or +02:00 UTC.
Instead of replacing the timezone of the datetime.datetime object separately, we can also call datetime.datetime.now() with the timezone argument to get the timezone-aware object right away:
>>> now = datetime.datetime.now(zoneinfo.ZoneInfo("localtime"))
>>> now
datetime.datetime(2024, 2, 17, 12, 53, 12, 528517, tzinfo=zoneinfo.ZoneInfo(key='localtime'))
>>> print(now)
2024-02-17 12:53:12.528517+02:00
>>>
Now, let’s take another timestamp that’s in UTC, like any timestamp data that you usually get from API calls:
>>> some_timestamp = datetime.datetime.fromisoformat("2024-02-17 11:00:00").replace(tzinfo=datetime.timezone.utc)
>>> some_timestamp
datetime.datetime(2024, 2, 17, 11, 0, tzinfo=datetime.timezone.utc)
>>>
We can then compare the timestamps:
>>> print(now) 2024-02-17 12:53:12.528517+02:00 >>> print(some_timestamp) 2024-02-17 11:00:00+00:00 >>> now > some_timestamp False >>>
That’s correct, because:
>>> print(some_timestamp.astimezone(zoneinfo.ZoneInfo("localtime")))
2024-02-17 13:00:00+02:00
>>>
We can also use whatever IANA timezone names are available:
>>> len(zoneinfo.available_timezones())
596
>>> sorted([tz for tz in zoneinfo.available_timezones() if "US/" in tz])
['US/Alaska', 'US/Aleutian', 'US/Arizona', 'US/Central', 'US/East-Indiana', 'US/Eastern', 'US/Hawaii', 'US/Indiana-Starke', 'US/Michigan', 'US/Mountain', 'US/Pacific', 'US/Samoa']
>>> print(now.astimezone(zoneinfo.ZoneInfo("US/Pacific")))
2024-02-17 02:53:12.528517-08:00
>>>
If you need to get the current UTC offset for some reason, you can get it via the datetime.utcoffset() method:
>>> now.utcoffset()
datetime.timedelta(seconds=7200)
>>> now.utcoffset().total_seconds()
7200.0
>>> datetime.datetime.now(zoneinfo.ZoneInfo("US/Pacific")).utcoffset().total_seconds()
-28800.0
>>>