Reputation: 2476
I have variable which holds time which is of type datetime.time in UTC, I wanted it to convert to some other timezone.
we can convert timezones in datetime.datetime instance as shown in this SO link - How do I convert local time to UTC in Python?. I am not able to figure out how to convert timezones in datetime.time instances. I can't use astimezone because datetime.time doesn't have this method.
For example:
>>> t = d.datetime.now().time()
>>> t
datetime.time(12, 56, 44, 398402)
>>>
I need 't' in UTC format.
Upvotes: 19
Views: 46423
Reputation: 2442
Let's assume you need to convert EST time to UTC. Now, first of all, python datetime objects are not timezone aware by default. They take the system time. So if you create a datetime object by doing:
from datetime import datetime
date = datetime(2022, 4, 28, 18, 0, 0) # or date = datetime.now() or strftime(), there are so many ways
date
would not be timezone aware. We can use pytz to make datetimes timezonz aware and then convert between timezones using localize
.
import pytz
from datetime import datetime
est = pytz.timezone('Europe/Paris')
utc = pytz.utc
We make the datetime timezone aware first.
est_time = est.localize(date)
then we can change the timezone and get the relvant time as we wish.
utc_time = est_time.astimezone(utc)
The full list of timezone strings are available at:
pytz.all_timezones
Upvotes: 1
Reputation: 1289
There are four cases:
datetime.time
has tzinfo
set (eg OP mentions UTC)
tzinfo
not set)datetime.time
has tzinfo
not set
tzinfo
not set)The correct answer needs to make use of datetime.datetime.timetz()
function because datetime.time
cannot be built as a non-naive timestamp by calling localize()
or astimezone()
directly.
from datetime import datetime, time
import pytz
def timetz_to_tz(t, tz_out):
return datetime.combine(datetime.today(), t).astimezone(tz_out).timetz()
def timetz_to_tz_naive(t, tz_out):
return datetime.combine(datetime.today(), t).astimezone(tz_out).time()
def time_to_tz(t, tz_out):
return tz_out.localize(datetime.combine(datetime.today(), t)).timetz()
def time_to_tz_naive(t, tz_in, tz_out):
return tz_in.localize(datetime.combine(datetime.today(), t)).astimezone(tz_out).time()
Example based on OP requirement:
t = time(12, 56, 44, 398402)
time_to_tz(t, pytz.utc) # assigning tzinfo= directly would not work correctly with other timezones
datetime.time(12, 56, 44, 398402, tzinfo=<UTC>)
In case naive timestamp is wanted:
time_to_tz_naive(t, pytz.utc, pytz.timezone('Europe/Berlin'))
datetime.time(14, 56, 44, 398402)
The cases where the time() instance has already tzinfo
set are easier because datetime.combine
picks up the tzinfo
from the passed parameter, so we just need to convert to tz_out
.
Upvotes: 20
Reputation: 2257
Easy way to convert from/to UTC timezone using pytz:
import datetime, pytz
def time_to_utc(naive, timezone="Europe/Istanbul"):
local = pytz.timezone(timezone)
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
return utc_dt
def utc_to_time(naive, timezone="Europe/Istanbul"):
return naive.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(timezone))
# type(naive) """DateTime"""
# type(timezone) """String"""
Upvotes: 1
Reputation: 64298
I would create a temp datetime object, convert the tz, and extract the time again.
import datetime
def time_to_utc(t):
dt = datetime.datetime.combine(datetime.date.today(), t)
utc_dt = datetime_to_utc(dt)
return utc_dt.time()
t = datetime.datetime.now().time()
utc_t = time_to_utc(t)
where, datetime_to_utc
is any of the suggestions in the linked question.
Upvotes: 9