Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does python's datetime.datetime.strptime('201412', '%Y%m%d') not raise a ValueError?

In the format I am given, the date 2014-01-02 would be represented by "20140102". This is correctly parsed with the standard strptime:

>>> datetime.datetime.strptime("20140102", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)

In this format, "201412" would not be a valid date. The docs say that the "%m" directive is "Month as a zero-padded decimal number." It gives as examples "01, 02, ..., 12". The days directive "%d" is also supposed to be zero-padded.

Based on this, I expected that "201412" would be an invalid input with this format, so would raise a ValueError. Instead, it is interpreted as 2014-01-02:

>>> datetime.datetime.strptime("201412", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)

The question is: is there a way to specify "no seriously zero-padded only"? Or am I misunderstanding the term "zero-padded" in this context?

Note that the question is not about how to parse dates in this format, but about understanding the behavior of strptime.

like image 620
user2957943 Avatar asked Sep 16 '16 04:09

user2957943


2 Answers

According to the related issue on the Python tracker, with the example being like such (a bit of a modification to this question, however the concept is the exact same):

>>> datetime.datetime.strptime('20141110', '%Y%m%d').isoformat()
'2014-11-10T00:00:00'
>>> datetime.datetime.strptime('20141110', '%Y%m%d%H%M').isoformat()
'2014-01-01T01:00:00'

The above behavior is determined to be not a bug as explained by this comment which states that they conform to the OpenGroup strptime standard which specifies that "leading zeros are permitted but not required.".

I guess the workaround is to use regex or check that the length of the string is of length 8 before passing into strptime.

like image 109
metatoaster Avatar answered Oct 22 '22 06:10

metatoaster


If you look here at how the regex is defined for %m https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Lib/_strptime.py#L204

'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])"

You can see you can either have a 10-12, 01-09, or 1-9 as acceptable months.

like image 37
postelrich Avatar answered Oct 22 '22 08:10

postelrich