71

I have a datetime in utc time zone, for example:

utc_time = datetime.datetime.utcnow()

And a pytz timezone object:

tz = timezone('America/St_Johns')

What is the proper way to convert utc_time to the given timezone?

1

6 Answers 6

81

I think I got it:

pytz.utc.localize(utc_time, is_dst=None).astimezone(tz)

This line first converts the naive (time zone unaware) utc_time datetime object to a datetime object that contains a timezone (UTC). Then it uses the astimezone function to adjust the time according to the requested time zone.

Sign up to request clarification or add additional context in comments.

7 Comments

utc_time.replace(tzinfo=pytz.utc).astimezone(tz). Note: pytz.utc is a special case (zero utc offset, always). You don't need localize() call in this case. If you do keep it (for generality); then add tz.normalize() call around the expression (it might be necessary if the source timezone is not UTC).
@J.F.Sebastian the call to localize is needed because utc_time doesn't contain timezone information. Without it astimezone won't work.
@Tzach what do you think the replace() call does in my previous comment?
It works also for utc_timestamp as int with datetime.utcfromtimestamp(utc_timestamp), which returns a timezone not aware datetime object. But utc_time.replace doesn't do the time schift and only add a tzinfo.
@YingdingWang The question from almost 5 years ago is not using utcfromtimestamp. Also datetime.datetime.utcnow() sets tzinfo as None.
|
30

It's the exact purpose of fromutc function:

tz.fromutc(utc_time)

(astimezone function calls fromutc under the hood, but tries to convert to UTC first, which is unneeded in your case)

Comments

12

I agree with Tzach's answer. Just wanted to include that the is_dst parameter is not required:

pytz.utc.localize(datetime.utcnow()).astimezone(tz)

That code converts the current UTC time to a timezone aware current datetime.

Whereas the code below converts the current UTC time to a timezone aware datetime which is not necessarily current. The timezone is just appended into the UTC time value.

tz.localize(datetime.utcnow())

2 Comments

If you already have a timezone-aware datetime, then you just need to use astimezone: dt.astimezone(tz). See also this answer and the pytz docs.
user8808265's answer is much simpler.
8

May I recommend to use arrow? If I understood the question:

>>> import arrow
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2014-08-12T13:01:28.071624+00:00]>    
>>> local = utc.to("America/St_Johns")
>>> local
<Arrow [2014-08-12T10:31:28.071624-02:30]>

You can also use

tz.fromutc(utc_time)

1 Comment

Thank you. This library indeed looks as a good alternative to datetime, however my project is big and I don't want to create more confusion by using another date-time library. I will definitely consider using it in other projects.
5

Another very easy way:

Because utcnow method returns a naive object, so you have to convert the naive object into aware object. Using replace method you can convert a naive object into aware object. Then you can use the astimezone method to create new datetime object in a different time zone.

from datetime import datetime
import pytz    
utc_time = datetime.utcnow()
tz = pytz.timezone('America/St_Johns')

utc_time =utc_time.replace(tzinfo=pytz.UTC) #replace method      
st_john_time=utc_time.astimezone(tz)        #astimezone method
print(st_john_time)

1 Comment

replace method is a bad idea. It is random in its behaviour
0

You can also use the sample below, I use it for similar task

tz = pytz.timezone('America/St_Johns')
time_difference=tz.utcoffset(utc_time).total_seconds() #time difference between UTC and local timezones in 5:30:00 format
utc_time = date + timedelta(0,time_difference)

It works fast and you don't need to import additional libraries.

1 Comment

This is wrong for timezones with daylight savings, because it doesn't account for them. See this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.