17

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.

Community
  • 1
  • 1
rajpy
  • 2,436
  • 5
  • 29
  • 43

4 Answers4

16

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.

Dorian B.
  • 1,101
  • 13
  • 22
9

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.

Community
  • 1
  • 1
shx2
  • 61,779
  • 13
  • 130
  • 153
  • 1
    Ok, is it not possible to convert timezone using datetime.time instance. Googled it didn't find anything. Your method is fine, but it takes too much time. Is there any better way? Thanks. – rajpy May 17 '13 at 08:15
1

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"""
Tarek Kalaji
  • 2,149
  • 27
  • 30
  • 1
    you might want to explain your code, and is naive supposed to be native, like your local timezone??? – 3kstc Nov 09 '16 at 01:01
  • 1
    Where `naive` is a `datetime` object without a timezone and `timezone` is a string matching one of the `pytz.timezone` names. [The datetime documentation](https://docs.python.org/2/library/datetime.html) briefly explains naive vs aware `datetime` objects. – travisw Oct 03 '17 at 19:18
1

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
toing_toing
  • 2,334
  • 1
  • 37
  • 79