Почему python datetime.datetime.strptime('201412', '% Y% m% d') не вызывает значение ValueError?
В формате, который мне дано, дата 2014-01-02 будет представлена "20140102". Это правильно проанализировано стандартным strptime:
>>> datetime.datetime.strptime("20140102", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)
В этом формате "201412" не будет действительной датой. docs говорят, что директива "% m" - "месяц как десятичное число с нулевым запасом". Он дает в качестве примеров "01, 02,..., 12". Директива дней "% d" также должна быть нулевой.
Исходя из этого, я ожидал, что "201412" будет недопустимым вводом этого формата, поэтому повысит значение ValueError. Вместо этого он интерпретируется как 2014-01-02:
>>> datetime.datetime.strptime("201412", "%Y%m%d")
datetime.datetime(2014, 1, 2, 0, 0)
Вопрос в том, есть ли способ указать "нет серьёзного нуля"? Или я не понимаю термин "нуль-padded" в этом контексте?
Обратите внимание, что вопрос заключается не в том, как разбирать даты в этом формате, а о понимании поведения strptime.
Ответы
Ответ 1
В соответствии с соответствующим issue на трекере Python, например, пример (немного модификация этого вопроса, однако концепция точно такой же):
>>> 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'
Вышеуказанное поведение определяется как не ошибка, поясняемая этим комментарием, в котором говорится, что они соответствуют стандарт strptime OpenGroup, который указывает, что "ведущие нули разрешены, но не требуются".
Я предполагаю, что обходным путем является использование регулярного выражения или проверка того, что длина строки имеет длину 8 до перехода в strptime
.
Ответ 2
Если вы посмотрите здесь, как определено регулярное выражение для %m
https://github.com/python/cpython/blob/2d264235f6e066611b412f7c2e1603866e0f7f1b/Lib/_strptime.py#L204
'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])"
Вы можете видеть, что вы можете иметь 10-12, 01-09 или 1-9 в качестве приемлемых месяцев.
Ответ 3
Это довольно сложно, но похоже, что strptime
просто пытается максимально соответствовать строке. Python strptime
- это то же самое, что и C strptime
, и в документах указано, что заполнение является необязательным:
- номер месяца [1,12]; допустимые начальные нули, но не требуется.
http://pubs.opengroup.org/onlinepubs/7908799/xsh/strptime.html