70

Let's say I have a variable t that's set to this:

datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=<UTC>) 

If I say str(t), i get:

'2009-07-10 18:44:59.193982+00:00' 

How can I get a similar string, except printed in the local timezone rather than UTC?

2

7 Answers 7

90

As of python 3.6 calling astimezone() without a timezone object defaults to the local zone (docs). This means you don't need to import tzlocal and can simply do the following:

#!/usr/bin/env python3 from datetime import datetime, timezone utc_dt = datetime.now(timezone.utc) print("Local time {}".format(utc_dt.astimezone().isoformat())) 

This script demonstrates a few other ways to show the local timezone using astimezone():

#!/usr/bin/env python3 import pytz from datetime import datetime, timezone from tzlocal import get_localzone utc_dt = datetime.now(timezone.utc) PST = pytz.timezone("US/Pacific") EST = pytz.timezone("US/Eastern") JST = pytz.timezone("Asia/Tokyo") NZST = pytz.timezone("Pacific/Auckland") print("Pacific time {}".format(utc_dt.astimezone(PST).isoformat())) print("Eastern time {}".format(utc_dt.astimezone(EST).isoformat())) print("UTC time {}".format(utc_dt.isoformat())) print("Japan time {}".format(utc_dt.astimezone(JST).isoformat())) # Use astimezone() without an argument print("Local time {}".format(utc_dt.astimezone().isoformat())) # Use tzlocal get_localzone print("Local time {}".format(utc_dt.astimezone(get_localzone()).isoformat())) # Explicitly create a pytz timezone object # Substitute a pytz.timezone object for your timezone print("Local time {}".format(utc_dt.astimezone(NZST).isoformat())) 

It outputs the following:

$ ./timezones.py Pacific time 2019-02-22T17:54:14.957299-08:00 Eastern time 2019-02-22T20:54:14.957299-05:00 UTC time 2019-02-23T01:54:14.957299+00:00 Japan time 2019-02-23T10:54:14.957299+09:00 Local time 2019-02-23T14:54:14.957299+13:00 Local time 2019-02-23T14:54:14.957299+13:00 Local time 2019-02-23T14:54:14.957299+13:00 
Sign up to request clarification or add additional context in comments.

2 Comments

By the way, python 3.6 supports the feature that astimezone() without tz represents system local time (refer).
@CodeUnsolved thanks for clarifying the behaviour of astimezone() called without a tz object.
40

Think your should look around: datetime.astimezone()

http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

Also see pytz module - it's quite easy to use -- as example:

eastern = timezone('US/Eastern') 

http://pytz.sourceforge.net/

Example:

from datetime import datetime import pytz from tzlocal import get_localzone # $ pip install tzlocal utc_dt = datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=pytz.utc) print(utc_dt.astimezone(get_localzone())) # print local time # -> 2009-07-10 14:44:59.193982-04:00 

5 Comments

So how do i get the current local timezone?
isn't datetime.datetime(2009, 7, 10, 18, 44, 59, 193982) - what you need?
This answer is wrong. I live in England and US/Eastern is NOT the local timezone.
@Muhail - No, because the resultant object is not datetime aware. You do not know what timezone you are in.
@Philluminati: tzlocal.get_localzone() gives you your local timezone.
13

I believe the best way to do this is to use the LocalTimezone class defined in the datetime.tzinfo documentation (goto http://docs.python.org/library/datetime.html#tzinfo-objects and scroll down to the "Example tzinfo classes" section):

Assuming Local is an instance of LocalTimezone

t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=utc) local_t = t.astimezone(Local) 

then str(local_t) gives:

'2009-07-11 04:44:59.193982+10:00' 

which is what you want.

(Note: this may look weird to you because I'm in New South Wales, Australia which is 10 or 11 hours ahead of UTC)

4 Comments

If you've defined Local per the datetime docs, this also works: str(datetime.datetime.now(tz=Local))
Be aware that this will print any use with the UTC offset that is currently in effect, which may not be the same that was or will be in effect at the time given by the datetime instance (due to DST).
LocalTimezone might fail for past dates if underlying time implementation doesn't use a historical timezone database (Windows is notably in this category).
I think the argument to astimezone should be empty: t.astimezone()
4

As of python 3.2, using only standard library functions:

u_tm = datetime.datetime.utcfromtimestamp(0) l_tm = datetime.datetime.fromtimestamp(0) l_tz = datetime.timezone(l_tm - u_tm) t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=l_tz) str(t) '2009-07-10 18:44:59.193982-07:00' 

Just need to use l_tm - u_tm or u_tm - l_tm depending whether you want to show as + or - hours from UTC. I am in MST, which is where the -07 comes from. Smarter code should be able to figure out which way to subtract.

And only need to calculate the local timezone once. That is not going to change. At least until you switch from/to Daylight time.

2 Comments

This doesn't take DST into account.
In base setup, it uses the delta between UTC and local for the epoch date. Anything else can not be 'automatic'. When displaying the final time, do you want to use DST if the current date is DST, or if the displayed date is/was/will be DST? So that needs to be determined by the surrounding program logic, and l_tz adjusted when appropriate. Possibly by taking a similar delta between Jan 1 and either the current or target date for the current or target year.
2

To set local time you can use timezone and timedelta together:

from datetime import datetime, timedelta, timezone my_current_time = datetime.now(tz=timezone(timedelta(hours=3))) print(my_current_time.__str__()) 

OUTPUT:

2024-04-03 16:06:40.939100+03:00 

Comments

0

I use this function datetime_to_local_timezone(), which seems overly convoluted but I found no simpler version of a function that converts a datetime instance to the local time zone, as configured in the operating system, with the UTC offset that was in effect at that time:

import time, datetime def datetime_to_local_timezone(dt): epoch = dt.timestamp() # Get POSIX timestamp of the specified datetime. st_time = time.localtime(epoch) # Get struct_time for the timestamp. This will be created using the system's locale and it's time zone information. tz = datetime.timezone(datetime.timedelta(seconds = st_time.tm_gmtoff)) # Create a timezone object with the computed offset in the struct_time. return dt.astimezone(tz) # Move the datetime instance to the new time zone. utc = datetime.timezone(datetime.timedelta()) dt1 = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, utc) # DST was in effect dt2 = datetime.datetime(2009, 1, 10, 18, 44, 59, 193982, utc) # DST was not in effect print(dt1) print(datetime_to_local_timezone(dt1)) print(dt2) print(datetime_to_local_timezone(dt2)) 

This example prints four dates. For two moments in time, one in January and one in July 2009, each, it prints the timestamp once in UTC and once in the local time zone. Here, where CET (UTC+01:00) is used in the winter and CEST (UTC+02:00) is used in the summer, it prints the following:

2009-07-10 18:44:59.193982+00:00 2009-07-10 20:44:59.193982+02:00 2009-01-10 18:44:59.193982+00:00 2009-01-10 19:44:59.193982+01:00 

1 Comment

It looks like Python 3.3+ code (.timestamp() method) In this case you could use a simpler code: dt.astimezone(tz=None). Also use timezone.utc instead of timezone(datetime.timedelta()).
0

I wrote something like this the other day:

import time, datetime def nowString(): # we want something like '2007-10-18 14:00+0100' mytz="%+4.4d" % (time.timezone / -(60*60) * 100) # time.timezone counts westwards! dt = datetime.datetime.now() dts = dt.strftime('%Y-%m-%d %H:%M') # %Z (timezone) would be empty nowstring="%s%s" % (dts,mytz) return nowstring 

So the interesting part for you is probably the line starting with "mytz=...". time.timezone returns the local timezone, albeit with opposite sign compared to UTC. So it says "-3600" to express UTC+1.

Despite its ignorance towards Daylight Saving Time (DST, see comment), I'm leaving this in for people fiddling around with time.timezone.

1 Comment

-1. This will return a wrong result half of the time, if you're in a timezone that uses DST. time.timezone contain the offset to UTC that is used when DST is not in effect, regardless of whether it currently is in effect.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.