wtarnawski
wtarnawski

Reputation: 19

Python datetime: format string %-m (%#m) unexpected behaviour

I am trying to format a date in format like '1/1/18' to a datetime object. I think a proper format string would be '%-m/%-d/%-y' (or '%#m/%#d/%#y' for Windows), but I couldn't confirm it with the official Python docs. I assume its m/d because of other dates I saw in the spreadsheet (5/28/2018, for example).

I think I have a problem with no-leading-zeros day, month and year. This site states that "%-m" (or "%#m" for Windows) would give me the month without a leading zero, so January would return 1 instead of 01. Let's try this:

>>> date_obj= datetime(year=2018, month=1, day=1)
>>> date_obj
datetime.datetime(2018, 1, 1, 0, 0)
>>> date_obj.strftime("%#m")
'1'

Works fine.

Let's run this through a complete date string.

>>> format_string = '%#m/%#d/%#y'
>>> date_obj.strftime(format_string)
'1/1/18'

Works fine too.

But when I try to parse this string with strptime function:

>>> datetime.strptime(format_string, '1/1/18')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\lib\_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\lib\_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '%#m/%#d/%#y' does not match format '1/1/18'

So actually a "circular use" of strptime and strftime results in an exception:

>>> datetime.strptime(
        format_string, 
        date_obj.strftime(format_string)
    )

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\lib\_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\lib\_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '%#m/%#d/%#y' does not match format '1/1/18'

What is a correct approach to converting a date string '1/1/18' to a datetime object?

I recreated this issue with the IPython console.

>>> import sys; print('Python %s on %s' % (sys.version, sys.platform))
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on win32

PS I'm not responsible for this date format, I know there are better ways of presenting dates. I was just asked to work on the data like this and am trying to make it more readable.

Upvotes: 1

Views: 3041

Answers (1)

Chillie
Chillie

Reputation: 1485

Your attributes are in reverse order.

It sohuld be datetime.strptime('1/1/18', format_string)

Minimal example:

from datetime import datetime as dt
dt.strptime('1/3/18','%m/%d/%y')

help() result on strptime:

Help on built-in function strptime:

strptime(...) string, format -> new datetime parsed from a string (like time.strptime()).

Upvotes: 1

Related Questions