I have two inputs time 00:00 and timezone 'Asia/Kolkata'
I want to convert this to UTC time like '18.30'
I don't want to add or subtract offsets because it may affect the day light saving
what i did is
local = pytz.timezone ("UTC")
nativetime = datetime.strptime (setTime,frmt)
local_dt = local.localize(nativetime, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
but this doesn't change anything, the time is not converted to UTC
Please help
Something like this, assuming you're on py3:
>>> import datetime
>>> import pytz
>>> tz = pytz.timezone('Asia/Kolkata')
>>> dt = datetime.datetime(2020, 8, 4, 0, 0, tzinfo=tz)
>>> dt.astimezone(pytz.utc)
datetime.datetime(2020, 8, 3, 18, 7, tzinfo=<UTC>)
>>>
Since you say you're new to Python, it might be good to skip pytz since it's going to be deprecated with Python 3.9. You can use dateutil instead, which can be replaced more easily with zoneinfo in Python 3.9.
from datetime import datetime, timezone
from dateutil.tz import gettz
# assuming you have something like
dt_naive = datetime.strptime('2020-08-05', '%Y-%m-%d')
# dt_naive has no time zone info, so set it:
dt_aware = dt_naive.replace(tzinfo=gettz('Asia/Kolkata'))
# now you can convert to another timezone using .astimezone:
dt_aware_utc = dt_aware.astimezone(timezone.utc)
# datetime.datetime(2020, 8, 4, 18, 30, tzinfo=datetime.timezone.utc)
# -> 5:30 hours behind, which matches dt_aware.utcoffset()
#thebjorn gave me the answer
here is what i did
def utc_to_local(utc_dt,local_tz):
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
return local_tz.normalize(local_dt)
setTime='00:00:00'
setZone='Asia/Kolkata'
datePart = str(datetime.utcnow()).split(' ')[0]
dateTimeUtcStr = datePart+' '+str(setTime)
tz = pytz.timezone('Asia/Kolkata')
tz_utc = pytz.timezone('UTC')
dateTimeRef = datetime.strptime(dateTimeUtcStr, '%Y-%m-%d %H:%M:%S')
#local to utc
tzUtc = pytz.timezone('UTC')
local_dt = tz.localize(dateTimeRef, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
print(utc_dt)
#utc to local
altTime = utc_to_local(utc_dt,tz)
print(altTime)
I travel frequently but live in NYC and am trying to display NYC time no matter where I am. How do I do that in Python? I have the following, which doesn't work, giving me the error:
`'module' object is not callable`
Also, I'm not sure if my method below will correctly update with daylight savings time or not:
import pytz
utc = pytz.utc
utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
eastern = pytz.timezone('US/Eastern')
loc_dt = utc_dt.astimezone(eastern)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
loc_dt.strftime(fmt)
Instead of datetime, write datetime.datetime:
import datetime
import pytz
utc = pytz.utc
utc_dt = datetime.datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
eastern = pytz.timezone('US/Eastern')
loc_dt = utc_dt.astimezone(eastern)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
loc_dt.strftime(fmt)
That's because the module datetime contains a class datetime.datetime.
You can get a datetime object of the current time in a specific timezone using the now() method in the following fashion:
import datetime, pytz
nyc_datetime = datetime.datetime.now(pytz.timezone('US/Eastern'))
It's cleaner to write your import like this:
from datetime import datetime
import pytz
now = datetime.now(tz=pytz.timezone('US/Eastern'))
This allows re-use of datetime further down your code, without having to datetime.datetime every single time. Also avoids importing the entire datetime module unnecessarily.
Also note that according to IANA, 'US/Eastern' has been deprecated. Perhaps consider 'America/New_York'
i will do this instead:
import datetime
import pytz
now = datetime.datetime.now(tz=pytz.timezone('US/Eastern'))
print("now time is: ", now)
current_hour = now.hour
current_minute = now.minute
current_second = now.second
current_weekday = now.weekday()
New in Python 3.9, you may choose zoneinfo instead of third party library
from zoneinfo import ZoneInfo
from datetime import datetime
dt = datetime(2022, 11, 16, 1, tzinfo=ZoneInfo("US/Eastern"))
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
dt.strftime(fmt)
How do I convert a time to another timezone in Python?
I have found that the best approach is to convert the "moment" of interest to a utc-timezone-aware datetime object (in python, the timezone component is not required for datetime objects).
Then you can use astimezone to convert to the timezone of interest (reference).
from datetime import datetime
import pytz
utcmoment_naive = datetime.utcnow()
utcmoment = utcmoment_naive.replace(tzinfo=pytz.utc)
# print "utcmoment_naive: {0}".format(utcmoment_naive) # python 2
print("utcmoment_naive: {0}".format(utcmoment_naive))
print("utcmoment: {0}".format(utcmoment))
localFormat = "%Y-%m-%d %H:%M:%S"
timezones = ['America/Los_Angeles', 'Europe/Madrid', 'America/Puerto_Rico']
for tz in timezones:
localDatetime = utcmoment.astimezone(pytz.timezone(tz))
print(localDatetime.strftime(localFormat))
# utcmoment_naive: 2017-05-11 17:43:30.802644
# utcmoment: 2017-05-11 17:43:30.802644+00:00
# 2017-05-11 10:43:30
# 2017-05-11 19:43:30
# 2017-05-11 13:43:30
So, with the moment of interest in the local timezone (a time that exists), you convert it to utc like this (reference).
localmoment_naive = datetime.strptime('2013-09-06 14:05:10', localFormat)
localtimezone = pytz.timezone('Australia/Adelaide')
try:
localmoment = localtimezone.localize(localmoment_naive, is_dst=None)
print("Time exists")
utcmoment = localmoment.astimezone(pytz.utc)
except pytz.exceptions.NonExistentTimeError as e:
print("NonExistentTimeError")
Using pytz
from datetime import datetime
from pytz import timezone
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
timezonelist = ['UTC','US/Pacific','Europe/Berlin']
for zone in timezonelist:
now_time = datetime.now(timezone(zone))
print now_time.strftime(fmt)
import datetime
import pytz
def convert_datetime_timezone(dt, tz1, tz2):
tz1 = pytz.timezone(tz1)
tz2 = pytz.timezone(tz2)
dt = datetime.datetime.strptime(dt,"%Y-%m-%d %H:%M:%S")
dt = tz1.localize(dt)
dt = dt.astimezone(tz2)
dt = dt.strftime("%Y-%m-%d %H:%M:%S")
return dt
-
dt: date time string
tz1: initial time zone
tz2: target time zone
-
> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "PST8PDT")
'2017-05-13 05:56:32'
> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "UTC")
'2017-05-13 12:56:32'
-
> pytz.all_timezones[0:10]
['Africa/Abidjan',
'Africa/Accra',
'Africa/Addis_Ababa',
'Africa/Algiers',
'Africa/Asmara',
'Africa/Asmera',
'Africa/Bamako',
'Africa/Bangui',
'Africa/Banjul',
'Africa/Bissau']
Python 3.9 adds the zoneinfo module so now only the the standard library is needed!
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> d = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo('America/Los_Angeles'))
>>> d.astimezone(ZoneInfo('Europe/Berlin')) # 12:00 in Cali will be 20:00 in Berlin
datetime.datetime(2020, 10, 31, 20, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
Wikipedia list of available time zones
Some functions such as now() and utcnow() return timezone-unaware datetimes, meaning they contain no timezone information. I recommend only requesting timezone-aware values from them using the keyword tz=ZoneInfo('localtime').
If astimezone gets a timezone-unaware input, it will assume it is local time, which can lead to errors:
>>> datetime.utcnow() # UTC -- NOT timezone-aware!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 376479)
>>> datetime.now() # Local time -- NOT timezone-aware!!
datetime.datetime(2020, 6, 2, 0, 39, 57, 376675)
>>> datetime.now(tz=ZoneInfo('localtime')) # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376806, tzinfo=zoneinfo.ZoneInfo(key='localtime'))
>>> datetime.now(tz=ZoneInfo('Europe/Berlin')) # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376937, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
>>> datetime.utcnow().astimezone(ZoneInfo('Europe/Berlin')) # WRONG!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 377562, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
Windows has no system time zone database, so here an extra package is needed:
pip install tzdata
There is a backport to allow use in Python 3.6 to 3.8:
sudo pip install backports.zoneinfo
Then:
from backports.zoneinfo import ZoneInfo
Time conversion
To convert a time in one timezone to another timezone in Python, you could use datetime.astimezone():
so, below code is to convert the local time to other time zone.
datetime.datetime.today() - return current the local time
datetime.astimezone() - convert the time zone, but we have to pass the time zone.
pytz.timezone('Asia/Kolkata') -passing the time zone to pytz module
Strftime - Convert Datetime to string
# Time conversion from local time
import datetime
import pytz
dt_today = datetime.datetime.today() # Local time
dt_India = dt_today.astimezone(pytz.timezone('Asia/Kolkata'))
dt_London = dt_today.astimezone(pytz.timezone('Europe/London'))
India = (dt_India.strftime('%m/%d/%Y %H:%M'))
London = (dt_London.strftime('%m/%d/%Y %H:%M'))
print("Indian standard time: "+India+" IST")
print("British Summer Time: "+London+" BST")
List all the time zones
import pytz
for tz in pytz.all_timezones:
print(tz)
To convert a time in one timezone to another timezone in Python, you could use datetime.astimezone():
time_in_new_timezone = time_in_old_timezone.astimezone(new_timezone)
Given aware_dt (a datetime object in some timezone), to convert it to other timezones and to print the times in a given time format:
#!/usr/bin/env python3
import pytz # $ pip install pytz
time_format = "%Y-%m-%d %H:%M:%S%z"
tzids = ['Asia/Shanghai', 'Europe/London', 'America/New_York']
for tz in map(pytz.timezone, tzids):
time_in_tz = aware_dt.astimezone(tz)
print(f"{time_in_tz:{time_format}}")
If f"" syntax is unavailable, you could replace it with "".format(**vars())
where you could set aware_dt from the current time in the local timezone:
from datetime import datetime
import tzlocal # $ pip install tzlocal
local_timezone = tzlocal.get_localzone()
aware_dt = datetime.now(local_timezone) # the current time
Or from the input time string in the local timezone:
naive_dt = datetime.strptime(time_string, time_format)
aware_dt = local_timezone.localize(naive_dt, is_dst=None)
where time_string could look like: '2016-11-19 02:21:42'. It corresponds to time_format = '%Y-%m-%d %H:%M:%S'.
is_dst=None forces an exception if the input time string corresponds to a non-existing or ambiguous local time such as during a DST transition. You could also pass is_dst=False, is_dst=True. See links with more details at Python: How do you convert datetime/timestamp from one timezone to another timezone?
For Python timezone conversions, I use the handy table from the PyCon 2012 presentation by Taavi Burns.
Please note: The first part of this answer is or version 1.x of pendulum. See below for a version 2.x answer.
I hope I'm not too late!
The pendulum library excels at this and other date-time calculations.
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.datetime.strptime(heres_a_time, '%Y-%m-%d %H:%M %z')
>>> for tz in some_time_zones:
... tz, pendulum_time.astimezone(tz)
...
('Europe/Paris', <Pendulum [1996-03-25T17:03:00+01:00]>)
('Europe/Moscow', <Pendulum [1996-03-25T19:03:00+03:00]>)
('America/Toronto', <Pendulum [1996-03-25T11:03:00-05:00]>)
('UTC', <Pendulum [1996-03-25T16:03:00+00:00]>)
('Canada/Pacific', <Pendulum [1996-03-25T08:03:00-08:00]>)
('Asia/Macao', <Pendulum [1996-03-26T00:03:00+08:00]>)
Answer lists the names of the time zones that may be used with pendulum. (They're the same as for pytz.)
For version 2:
some_time_zones is a list of the names of the time zones that might be used in a program
heres_a_time is a sample time, complete with a time zone in the form '-0400'
I begin by converting the time to a pendulum time for subsequent processing
now I can show what this time is in each of the time zones in show_time_zones
...
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.from_format('1996-03-25 12:03 -0400', 'YYYY-MM-DD hh:mm ZZ')
>>> for tz in some_time_zones:
... tz, pendulum_time.in_tz(tz)
...
('Europe/Paris', DateTime(1996, 3, 25, 17, 3, 0, tzinfo=Timezone('Europe/Paris')))
('Europe/Moscow', DateTime(1996, 3, 25, 19, 3, 0, tzinfo=Timezone('Europe/Moscow')))
('America/Toronto', DateTime(1996, 3, 25, 11, 3, 0, tzinfo=Timezone('America/Toronto')))
('UTC', DateTime(1996, 3, 25, 16, 3, 0, tzinfo=Timezone('UTC')))
('Canada/Pacific', DateTime(1996, 3, 25, 8, 3, 0, tzinfo=Timezone('Canada/Pacific')))
('Asia/Macao', DateTime(1996, 3, 26, 0, 3, 0, tzinfo=Timezone('Asia/Macao')))
For Python 3.2+ simple-date is a wrapper around pytz that tries to simplify things.
If you have a time then
SimpleDate(time).convert(tz="...")
may do what you want. But timezones are quite complex things, so it can get significantly more complicated - see the the docs.
# Program
import time
import os
os.environ['TZ'] = 'US/Eastern'
time.tzset()
print('US/Eastern in string form:',time.asctime())
os.environ['TZ'] = 'Australia/Melbourne'
time.tzset()
print('Australia/Melbourne in string form:',time.asctime())
os.environ['TZ'] = 'Asia/Kolkata'
time.tzset()
print('Asia/Kolkata in string form:',time.asctime())
I have...
entity = simplejson.dumps({"a":unicode(datetime.datetime.utcnow())})
How do I convert the datetime (that was converted to unicode) back to datetime again?
So that I can do something like...
entity2 = simplejson.loads(entity)
#your answer here..
add5 = entity2["a"] + datetime.timedelta(minutes=5)
Thanks!
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
Do the following before serializing:
time = datetime.strftime(time, DATETIME_FORMAT)
Do the following after unserializing:
time = datetime.strptime(time, DATETIME_FORMAT)
example:
>>> from datetime import datetime
>>> DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
>>> time = datetime.now()
>>> time
datetime.datetime(2011, 5, 5, 3, 1, 45, 646302)
>>> time = time.strftime(DATETIME_FORMAT)
>>> time
'2011-05-05 03:01:45'
>>> import json
>>> time = json.loads(json.dumps(time))
>>> time
'2011-05-05 03:01:45'
>>> time = datetime.strptime(time, DATETIME_FORMAT)
>>> time
datetime.datetime(2011, 5, 5, 3, 1, 45)
In case you find this somewhat inelegant, you might consider a custom json encoder/decoder. I personally have tried the ones in the default json package, but gave up pulling my hair out with cryptic error messages. If you go this path, I might recommend a third party json package.
Use datetime.datetime.strptime.
dt = datetime.datetime.strptime(entity2['a'], '%Y-%m-%d %H:%M:%S.%f')