Using Python datetime with Timezones
Jump to navigation
Jump to search
Links
Distinguishing between TZ Aware and TZ Naive Objects
from datetime import datetime
now = datetime.now()
now = now.replace(tzinfo=datetime.timezone.utc)
if now.tzinfo == None or \
now.tzinfo.utcoffset(now) == None:
# If these conditions are met the object is unaware
print("Unaware")
else:
print("Aware")
print(now.isoformat())
Binding with Timezone Info
cat !$
cat ./py_tz_example_01.py
#!/usr/bin/env python3
import pytz
from datetime import datetime
def list_tz():
for tz in pytz.all_timezones:
print(tz)
def example(tz_name):
specified_tz = pytz.timezone(tz_name)
# transform to a time using a specific timezone
tz_aware_dt = datetime.now(tz=specified_tz)
print(f"TZ aware datetime value |{tz_aware_dt.isoformat()}| for timezone - '{tz_name}'")
# list_tz()
print(f"TZ naive datetime value |{datetime.now().isoformat()}|")
example("America/New_York")
example("America/Vancouver")
example("Asia/Tokyo")
example("Australia/Sydney")
example("Europe/London")
example("Europe/Paris")
Output
% ./py_tz_example_01.py TZ naive datetime value |2022-06-05T09:48:41.237251| TZ aware datetime value |2022-06-04T19:48:41.249310-04:00| for timezone - 'America/New_York' TZ aware datetime value |2022-06-04T16:48:41.249630-07:00| for timezone - 'America/Vancouver' TZ aware datetime value |2022-06-05T08:48:41.249701+09:00| for timezone - 'Asia/Tokyo' TZ aware datetime value |2022-06-05T09:48:41.249923+10:00| for timezone - 'Australia/Sydney' TZ aware datetime value |2022-06-05T00:48:41.250303+01:00| for timezone - 'Europe/London' TZ aware datetime value |2022-06-05T01:48:41.250543+02:00| for timezone - 'Europe/Paris'
Explicit Numerical Offsets from UTC
#!/usr/bin/env python3
from datetime import datetime, timezone
dt = datetime.now()
# This is a naive datetime value
print(f" TZ naive datetime value |{dt.isoformat()}|")
print(f" dt.tzinfo |{dt.tzinfo}|")
# Cast this as UTC
dt = dt.replace(tzinfo=timezone.utc)
# Define the offset
offset = "+1000" # "Australia/Melbourne"
# Convert as so...
tz_aware_dt = dt.astimezone(datetime.strptime(offset, "%z").tzinfo)
print(f" TZ Aware datetime value |{tz_aware_dt.isoformat()}|")
Output
% ./py_tz_example_02.py
TZ naive datetime value |2022-06-05T09:49:37.782118|
dt.tzinfo |None|
TZ Aware datetime value |2022-06-05T19:49:37.782118+10:00|
Changing Timezones
from pytz import timezone
from datetime import datetime
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
# Current datetime in UTC
dt = datetime.now(timezone('UTC'))
print(dt.strftime(fmt))
# Convert to US/Pacific time zone
dt = dt.astimezone(timezone('Asia/Tokyo'))
print(dt.strftime(fmt))
# Convert to Europe/Paris time zone
dt = dt.astimezone(timezone('Europe/Paris'))
print dt.strftime(fmt)
Output
./tst_ft.py 2022-06-05 09:41:02 UTC+0000 2022-06-05 18:41:02 JST+0900 2022-06-05 11:41:02 CEST+0200
Show System Timezone
import tzlocal
tzlocal.get_localzone()
# <DstTzInfo 'Asia/Taipei' LMT+8:06:00 STD>
tzlocal.get_localzone().zone
# 'Asia/Taipei'
from time import gmtime, strftime
print(strftime("%z", gmtime()))
# +0800
Find Timezones Of A Certain Country
import pytz
pytz.country_timezones('tw')
# ['Asia/Taipei']
pytz.country_timezones('cn')
# ['Asia/Shanghai', 'Asia/Urumqi']
Other Examples
Since dateutil uses the same timezone model as the datetime lib, you can set the tzinfo property straight away. You can also use .replace(tzinfo=...) safely.
import dateutil
aware_datetime = datetime(2020, 1, 5, 10, 12, tzinfo=dateutil.tz.gettz('Europe/London'))
print(aware_datetime)
# 2020-01-05 10:12:00+00:00
By the way, the procedure is identical if you use the zoneinfo module on Python 3.9:
from zoneinfo import ZoneInfo
aware_datetime = datetime(2020, 1, 5, 10, 12, tzinfo=ZoneInfo('Europe/London'))