rajpy
rajpy

Reputation: 2476

How to convert datetime.time from UTC to different timezone?

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

Answers (4)

toing_toing
toing_toing

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

Dorian B.
Dorian B.

Reputation: 1289

There are four cases:

  1. input datetime.time has tzinfo set (eg OP mentions UTC)
    1. output as non-naive time
    2. output as naive time (tzinfo not set)
  2. input datetime.time has tzinfo not set
    1. output as non-naive time
    2. output as naive time (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

Tarek Kalaji
Tarek Kalaji

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

shx2
shx2

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

Related Questions