0

There is a time string 2019-05-15T16:08:37+08:00 I got from front-end, and I want to convert it to a normal datetime object by using datetime

How can I do it correctly?

I tried

start_time_utc_s = "2019-05-15T16:08:37+08:00"
r = datetime.datetime.strptime(start_time_utc_s, "%Y-%m-%dT%H:%M:%S+08:00")

# print(r)
# 2019-05-15 16:08:37

but I don't think it's right...

jia Jimmy
  • 1,693
  • 2
  • 18
  • 38

1 Answers1

1

It's not right because you're simply discarding the timezone information (in this case, the UTC offset (+8 hours)).
For more details, check [Python 3.Docs]: datetime - strftime() and strptime() Behavior (%z directive).

>>> import datetime
>>>
>>> start_time = "2019-05-15T16:08:37+08:00"
>>>
>>> dt0 = datetime.datetime.strptime(start_time, "%Y-%m-%dT%H:%M:%S+08:00")
>>> dt0
datetime.datetime(2019, 5, 15, 16, 8, 37)
>>> dt0.tzinfo
>>>
>>> dt_format_string = "%Y-%m-%dT%H:%M:%S%z"  # This format string also takes timezone info (UTC offset) into account
>>> dt1 = datetime.datetime.strptime(start_time, dt_format_string)
>>> dt1
datetime.datetime(2019, 5, 15, 16, 8, 37, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800)))
>>> dt1.tzinfo
datetime.timezone(datetime.timedelta(seconds=28800))
>>>
>>> dt2 = datetime.datetime.strptime("2019-05-15T16:08:37+08:45", dt_format_string)  # Changed the offset to +08:45
>>> dt2
datetime.datetime(2019, 5, 15, 16, 8, 37, tzinfo=datetime.timezone(datetime.timedelta(seconds=31500)))

The time offset in question corresponds to a bunch of timezones: AWST, CST, HKT, IRKT, MYT, PHT, SGT, WITA, ... (check [TimeAndDate]: Time Zone Abbreviations – Worldwide List for the complete list).

@EDIT0:

Everything above is on Python 3.7(.3) (and it seems that the doc and functionality are NOT in sync).
On Python 3.6(.8):

>>> datetime.datetime.strptime("2019-05-15T16:08:37+08:45", "%Y-%m-%dT%H:%M:%S%z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\install\x64\python\python\03.06.08\Lib\_strptime.py", line 565, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "c:\install\x64\python\python\03.06.08\Lib\_strptime.py", line 362, in _strptime
    (data_string, format))
ValueError: time data '2019-05-15T16:08:37+08:45' does not match format '%Y-%m-%dT%H:%M:%S%z'

For that, as shown in:

one way would be to (install and) use dateutil:

>>> import sys
>>> sys.version
'3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)]'
>>>
>>> from dateutil import parser
>>> parser.parse("2019-05-15T16:08:37+08:00")
datetime.datetime(2019, 5, 15, 16, 8, 37, tzinfo=tzoffset(None, 28800))

Or you could strip out the (last) colon between hours and minutes (for UTC offset). Note that the below code relies on UTC offset being specified in the fixed format from the question:

>>> start_time = "2019-05-15T16:08:37+08:00"
>>>
>>> dt_format_string = "%Y-%m-%dT%H:%M:%S%z"
>>>
>>> datetime.datetime.strptime(start_time[:-3] + start_time[-2:], dt_format_string)
datetime.datetime(2019, 5, 15, 16, 8, 37, tzinfo=datetime.timezone(datetime.timedelta(0, 28800)))

But both these seem to be just workarounds.

CristiFati
  • 38,250
  • 9
  • 50
  • 87
  • Thanks for replying, but it seemed I have to convert `+08:00` to `+0800` at first? – jia Jimmy May 15 '19 at 09:31
  • No, you don't. It works just fine. Try using the same format on some thext like *"2019-05-15T16:08:37+08:30"*, you'll notice that it will correctly compute the difference. – CristiFati May 15 '19 at 09:35
  • But it failed in my trial , `ValueError: time data '2019-05-15T16:08:37+08:00' does not match format '%Y-%m-%dT%H:%M:%S%z'` as the doc said you mentioned above [doc](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior), I‘m using `python3.6`’ – jia Jimmy May 15 '19 at 09:42
  • You're welcome. This behavior difference between versions surprised me :). – CristiFati May 15 '19 at 10:32