You can do it with iso8601
or dateutil.parser
:
import iso8601
import dateutil.parser
from pytz import timezone
fmt = '%Y-%m-%d %H:%M:%S %Z'
ist = timezone('Asia/Kolkata')
str = '2017-07-30T10:00:00+05:30'
d = iso8601.parse_date(str).astimezone(ist)
print(d.strftime(fmt))
d = dateutil.parser.parse(str).astimezone(ist)
print(d.strftime(fmt))
The output for both cases is:
2017-07-30 10:00:00 IST
Note that I used Asia/Kolkata
instead of IST
. That's because these 3-letter names are ambiguous and not standard: IST
can be India Standard Time, Israel Standard Time or Irish Standard Time (this last one is also called Irish Summer Time, as it's the timezone used during Ireland's Daylight Saving Time).
Always prefer to use IANA timezones names (always in the format Continent/City
, like America/Sao_Paulo
or Europe/Berlin
). If Asia/Kolkata
is not what you need, check this list to find the one that suits best for your case.
If you don't know which timezone to use and want to guess based on the offset, I'm afraid is not that simple.
Using your input as example: the offset is +05:30
(5 hours and 30 minutes ahead of UTC). There's more than one timezone that uses this offset (or used once in its history). The wikipedia link contains 3, but I could find the following:
Asia/Dhaka, Asia/Calcutta, Asia/Karachi, Asia/Dacca, Asia/Thimbu, Asia/Katmandu, Asia/Thimphu, Asia/Kolkata, Asia/Colombo, Asia/Kathmandu
All of these timezones uses (or had used in the past) the +05:30
offset. As timezones can change during history, you have some problems when trying to guess the timezone based on the offset:
- you need to know what was the current offset at the specified date and time. In your case, you're using
2017-07-30
, but I'm assuming you want to handle any dates in the past.
- there can be more than one timezone with the valid offset at the specified date and time (then you'll have to choose one, based on any arbitrary criteria).
- some timezones, depending on the date, can be in Daylight Saving Time, which means that the offset won't be
+05:30
(or even worse, some might use +05:30
during DST).
So, you can't get just one single timezone, based on the offset. The best you can do is to get a list of candidates: a list with all timezones in which the offset was valid at the respective date/time. Then you'll have to choose one of them (maybe if you have a list of "prefered ones"):
str = '2017-07-30T10:00:00+05:30'
# parse date and get the offset (in this case, +05:30)
d = iso8601.parse_date(str)
offset = d.tzinfo.utcoffset(d)
# a set with all candidate timezones
zones = set()
# find a zone where the offset is valid for the date
for tz in pytz.all_timezones:
zone = timezone(tz)
# get the offset for the zone at the specified date/time
zoneoffset = zone.utcoffset(d.replace(tzinfo=None))
if (zoneoffset == offset):
zones.add(zone)
# just checking all the candidates timezones
for z in zones:
print(z, d.astimezone(z).strftime(fmt))
The output will be:
Asia/Kolkata 2017-07-30 10:00:00 IST
Asia/Colombo 2017-07-30 10:00:00 +0530
Asia/Calcutta 2017-07-30 10:00:00 IST
Note that 3 timezones were found (Kolkata, Colombo and Calcutta). That's because all these 3 timezones have a valid offset of +05:30
on 2017-07-30
. For some reason, Colombo were not formatted as IST
: I think it depends on how this timezone is configured in Python, or my version is not updated (I'm using Python 3.5.2) - I've tested this in Java and it's formatted as IST
, so probably it's a configuration issue in my Python instalation.
Once you have all the candidates timezones, you'll have to choose one (and I'm not sure what would be the best criteria for that).
PS: actually there are only 2 options, because Asia/Kolkata
and Asia/Calcutta
are synonyms. But you still have more than one option and the question remains: which one to choose?