Let\'s say I have a variable t that\'s set to this:
datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=)
If I say s
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
.
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.
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
This script demonstrates a few 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
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()))
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
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)