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 >>>