13

I have the following datetime string s:

2017-10-18T04:46:53.553472514Z

I parese it like that:

t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%SZ')

how to fix ValueError: time data '2017-10-18T04:46:53.553472514Z' does not match format '%Y-%m-%dT%H:%M:%SZ'

FObersteiner
  • 22,500
  • 8
  • 42
  • 72

5 Answers5

19

In theory,

t = datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%fZ')

would be the correct format string as you have fractions of second as well. BUT they would then need to be microseconds. Yours are probably nanoseconds, as %f only takes maximum of 6 digits.

So you need to do something like this:

t = datetime.datetime.strptime(s.split(".")[0], '%Y-%m-%dT%H:%M:%S')
t = t + datetime.timedelta(microseconds=int(s.split(".")[1][:-1])/1000)

print (t)

This works but it converts nanoseconds to microseconds. If this is not ok, then you need to do something else.

Hannu
  • 11,685
  • 4
  • 35
  • 51
7

I think you should use dateutil.parser module

In [23]: s = "2017-10-18T04:46:53.553472514Z"

In [24]: import dateutil.parser as p

In [25]: p.parse(s)
Out[25]: datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())
not_python
  • 904
  • 6
  • 13
1

As @FObersteiner pointed out, %z parses Z as well as ±HHMM[SS[.ffffff]] style of timezone encoding.

This information is hidden in the technical detail #6. :-/

Previous incorrect answer:

To answer the original question: there's no way to parse "Z" as the timezone using only the standard library.~

Here's some discussion on that: https://bugs.python.org/issue35829

Javier
  • 2,752
  • 15
  • 30
  • `%z` *does* parse Z. – FObersteiner Jan 23 '23 at 13:03
  • In `datetime.strptime`, `%z` parses the UTC offset in the form `±HHMM[SS[.ffffff]]`. See https://docs.python.org/3.10/library/datetime.html#strftime-and-strptime-format-codes. – Javier Jan 24 '23 at 08:21
  • Thank you for coming back to this post. Please note the [technical detail](https://docs.python.org/3.10/library/datetime.html#technical-detail) #6, "*[...] In addition, providing 'Z' is identical to '+00:00'*". – FObersteiner Jan 24 '23 at 09:06
  • You are 100% correct! – Javier Feb 05 '23 at 14:59
0

datetime is another Python built-in module that is completely superseded by a better extra module: arrow.

You can just do:

import arrow
dt = arrow.get('2017-10-18T04:46:53.553472514Z').datetime

Your date string being in standardized ISO format, it will be parsed without even giving a format string. The parsed df will be:

datetime.datetime(2017, 10, 18, 4, 46, 53, 553472, tzinfo=tzutc())

Or keep the Arrow object in case you want to keep the extra precision

Ken Williams
  • 22,756
  • 10
  • 85
  • 147
Guillaume
  • 5,497
  • 3
  • 24
  • 42
  • 5
    Who decides that a built-in module is superseded by a random external module? – km6 Jul 06 '21 at 16:05
  • 2
    @km6: basically, it's you who decide if you prefer to use only the standard library + your own code to fill the gaps, or if you want to rely on external modules that will make your life easier. But it is generally admitted that the standard library is the place where modules go to die. Once in the standard library, they don't evolve much. Some good examples: urllib.request is obsoleted by requests/httpx (to the point that even the official doc recommends to use it: https://docs.python.org/3.9/library/urllib.request.html#module-urllib.request ). LXML implements a much faster xml parser. etc. – Guillaume Jul 13 '21 at 07:34
0

I like the mx.DateTime module.

import mx.DateTime as dt
dt.DateTimeFrom('2017-10-18T04:46:53.553472514Z')
Daniel Leon
  • 31
  • 1
  • 5