0

I have checked this line over and over and cannot find where the mismatch is on this error. Maybe another set of eyes can tell me?

ValueError: time data

'2019-07-17T00:00:00.000000000Z' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'

Where is the mismatch?

**UPDATE*****

The 2019-07-17T00:00:00.000000000Z is part of a JSON stream:

{
  "volume": 82, 
  "mid": {
    "h": "1.12286", 
    "c": "1.12272", 
    "l": "1.12267", 
    "o": "1.12274"
  }, 
  "complete": true, 
  "time": "2019-07-17T23:00:00.000000000Z"
}, 
{
  "volume": 10, 
  "mid": {
    "h": "1.12284", 
    "c": "1.12272", 
    "l": "1.12272", 
    "o": "1.12274"
  }, 
  "complete": false, 
  "time": "2019-07-18T00:00:00.000000000Z"
}

This is exactly as received, and I am sending the time value into this function:

time.mktime(time.strptime(str(json['time']), '%Y-%m-%dT%H:%M:%S.%fZ')))
cube
  • 1,774
  • 4
  • 23
  • 33
  • Possible duplicate of [Parsing datetime strings containing nanoseconds](https://stackoverflow.com/questions/10611328/parsing-datetime-strings-containing-nanoseconds) – Adrian Shum Jul 18 '19 at 02:01
  • OK, based on the answers below, this is required `json['time'].replace('000', '', 1)` to remove the additional 3 zeros in the microseconds. – cube Jul 18 '19 at 03:14
  • wrong. if you got a string with `2000-11-11T11:11:11T00000000Z`, you are doomed – Adrian Shum Jul 18 '19 at 03:35
  • and, the extra update is not meaningful: it makes no difference where the string is coming from. – Adrian Shum Jul 18 '19 at 03:45

2 Answers2

2

It is a problem you can find out by yourselves simply by adjusting the date and format:

Fail:

d = datetime.strptime("2019-07-17T00:00:00.000000000Z", "%Y-%m-%dT%H:%M:%S.%fZ")

Success:

d = datetime.strptime("2019-07-17T00:00:00", "%Y-%m-%dT%H:%M:%S")

Which means the problem comes from the %fZ part.

From Python document, %f means microsecond which means 6 digits.

d = datetime.strptime("2019-07-17T00:00:00.000000Z", "%Y-%m-%dT%H:%M:%S.%fZ")

That's the above will work


Edit: There are two choices you can have:

  1. If the incoming string always ends with 3 zeros for the nanosecond part, you can adjust your format to "%Y-%m-%dT%H:%M:%S.%f000Z"

  2. If you are not sure, then you can just trim off last 3 digits from the input string

One way you can do:

input_string = "2019-07-17T00:00:00.000000000Z"
result = datetime.strptime(input_string[:-4], "%Y-%m-%dT%H:%M:%S.%f")

Here I excluded the last 4 characters (000Z) from the string and the format is updated accordingly to remove the matching of last Z.

Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • Maybe I'll have to update my question. The `{'time':'2019-07-17T00:00:00.000000000Z'}` is part of a json stream that I receive and I'm sending it into `time.mktime(time.strptime(str(json['time']), '%Y-%m-%dT%H:%M:%S.%fZ')))` – cube Jul 18 '19 at 02:15
  • I think the answers here and in the duplicated question is clear on what you should do. No one care and it makes no difference where the string comes from: there is simply no way that Python `strptime` could parse nanosecond. You could trim off the last several digits from your in put, or, if the last 3 digits are always zero, you can put those extra zeros in your format string – Adrian Shum Jul 18 '19 at 02:20
1

The documentation has a note about %f (to be fair a footnote):

When used with the strptime() method, the %f directive accepts from one to six digits and zero pads on the right. %f is an extension to the set of format characters in the C standard (but implemented separately in datetime objects, and therefore always available).

If you remove some of the zeros from the microseconds the format string works fine:

datetime.strptime('2019-07-17T00:00:00.000000Z', '%Y-%m-%dT%H:%M:%S.%fZ')
# datetime.datetime(2019, 7, 17, 0, 0)
Mark
  • 90,562
  • 7
  • 108
  • 148