Search code examples
pythondatetimestrptime

ValueError: time data '2018-12-22T00:41:30.926932Z' does not match format '%Y-%m-%d %H:%M:%S'


I'm having troubles converting a time string to datetime object: And i know this question has been asked a couple of times but i haven't been able to find a solution for my question.

Here is my code:

order['created'] = 2018-12-22T00:41:30.926932Z
created_at = datetime.datetime.strptime(order['created'],'%m/%d/%Y %H:%M:%S.%f').replace(tzinfo=pytz.utc).astimezone(local_tz)

and this is the error message I get

ValueError: time data '2018-12-22T00:41:30.926932Z' does not match format '%m/%d/%Y %H:%M:%S.%f'


Solution

  • The first problem is that you have an ISO date in this format: 2018-12-22T00:41:30.926932Z but the format string your code is passing to strptime() specifies an American-style date with month first and slashes.

    So instead of "%m/%d/%Y %H:%M:%S.%f" you need "%Y-%m-%dT%H:%M:%S.%f".

    Things to notice about this:

    1. Year (%Y) comes first.
    2. Hyphens not slashes.
    3. T between date and time, not space.

    The second problem is that the data ends with a timezone string Z for GMT, but your code doesn't include that in the format spec. The proper format directive for this is %z. So, add %z at the end to get "%Y-%m-%dT%H:%M:%S.%f%z".

    The function strptime() is accurate but not bright, and cannot work out where your format spec doesn't match the data. All you get is a generic message that says data does not match format. At that point, it is up to you to go back to the documentation to discover where the mismatch is.

    Finally, .replace(tzinfo=pytz.utc).astimezone(local_tz) will not work because (unless you have defined local_tz in code you haven't presented), referencing local_tz will give a NameError or an AttributeError: I suspect that what you want is tzlocal.get_localzone(). You may have to install tzlocal for this to work. (There are other ways to do this, but this way is closest to the code you present.)

    After fixing these three problems I get

    >>> order['created'] = "2018-12-22T00:41:30.926932Z"
    

    Notice, you need quotes around the timestamp value, that must have been in your original code to result in the error message you report, but are not in your question. Always post the exact code that is giving the error message, not a retyped or redacted version.

    >>> datetime.datetime.strptime(order['created'],'%Y-%m-%dT%H:%M:%S.%f%z').replace(tzinfo=pytz.utc).astimezone(tzlocal.get_localzone())
    datetime.datetime(2018, 12, 22, 1, 41, 30, 926932, tzinfo=<DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>)
    

    which is correct but will probably not match your result because I live in The Hague.

    Working with dates is tricky at the best of times, and it nearly always requires a surprising degree of attention to detail.