I\'ve never had to convert time to and from UTC. Recently had a request to have my app be timezone aware, and I\'ve been running myself in circles. Lots of information on co
I traditionally defer this to the frontend -- send times from the backend as timestamps or some other datetime format in UTC, then let the client figure out the timezone offset and render this data in the proper timezone.
For a webapp, this is pretty easy to do in javascript -- you can figure out the browser's timezone offset pretty easily using builtin methods and then render the data from the backend properly.
From the answer here, you can use the time module to convert from utc to the local time set in your computer:
utc_time = time.strptime("2018-12-13T10:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
utc_seconds = calendar.timegm(utc_time)
local_time = time.localtime(utc_seconds)
You can use arrow
from datetime import datetime
import arrow
now = datetime.utcnow()
print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'
you can feed arrow.get()
with anything. timestamp, iso string etc
You can use calendar.timegm
to convert your time to seconds since Unix epoch and time.localtime
to convert back:
import calendar
import time
time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)
print time.ctime(t)
Gives Fri Jan 21 05:37:21 2011
(because I'm in UTC+03:00 timezone).
Here's a resilient method that doesn't depend on any external libraries:
from datetime import datetime
import time
def datetime_from_utc_to_local(utc_datetime):
now_timestamp = time.time()
offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
return utc_datetime + offset
This avoids the timing issues in DelboyJay's example. And the lesser timing issues in Erik van Oosten's amendment.
As an interesting footnote, the timezone offset computed above can differ from the following seemingly equivalent expression, probably due to daylight savings rule changes:
offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!
Update: This snippet has the weakness of using the UTC offset of the present time, which may differ from the UTC offset of the input datetime. See comments on this answer for another solution.
To get around the different times, grab the epoch time from the time passed in. Here's what I do:
def utc2local (utc):
epoch = time.mktime(utc.timetuple())
offset = datetime.fromtimestamp (epoch) - datetime.utcfromtimestamp (epoch)
return utc + offset
If you don't want to provide your own tzinfo
objects, check out the python-dateutil library. It provides tzinfo
implementations on top of a zoneinfo (Olson) database such that you can refer to time zone rules by a somewhat canonical name.
from datetime import datetime
from dateutil import tz
# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')
# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')
# Tell the datetime object that it's in UTC time zone since
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)
# Convert time zone
central = utc.astimezone(to_zone)
Edit Expanded example to show strptime
usage
Edit 2 Fixed API usage to show better entry point method
Edit 3 Included auto-detect methods for timezones (Yarin)