Datetime Timezones from String

Tags: , ,



I am trying to figure out how to make a datetime object aware through using a variable. I grab the timezone of the user and pass it through a form to be used.

I have tried both of the below methods and am not having much success

timezone_variable = "Europe/London"
new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                            int(time_hour), int(date_minute), tzinfo=timezone_variable)

new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                            int(time_hour), int(date_minute), tzinfo=timezone.timezone_variable)

This will then give me errors of TypeError: tzinfo argument must be None or of a tzinfo subclass, not type 'str'

The timezone will not always be known upfront, so it would not be possible to simply have the argument be as such tzinfo=timezone.utc.

Answer

Using dateutil or Python 3.9’s zoneinfo:

from datetime import datetime
from dateutil.tz import gettz
# from zoneinfo import ZoneInfo # Python 3.9

date_year, date_month, date_day, time_hour, date_minute = 2020, 10, 21, 10, 21

timezone_variable = gettz("Europe/London") # ZoneInfo("Europe/London") # Python 3.9

new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                        int(time_hour), int(date_minute), tzinfo=timezone_variable)
print(new_datetime) 
# 2020-10-21 10:21:00+01:00 
print(repr(new_datetime))
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=tzfile('GB-Eire'))

# with zoneinfo:
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=zoneinfo.ZoneInfo(key='Europe/London'))

Note: you can directly create a datetime object. If you use pytz (deprecated with Python 3.9), you must use the localize method of the timezone object. Otherwise, you’ll end up with LMT (local mean time):

import pytz
timezone_variable = pytz.timezone("Europe/London")

# not what you want (most of the time...):
new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                        int(time_hour), int(date_minute), tzinfo=timezone_variable)
print(repr(new_datetime))
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)

Side-note: interestingly, dateutil returns the deprecated GB-Eire time zone name for Europe/London. It is correct nevertheless, no worries.



Source: stackoverflow