How do I validate a date string format in python?


I have a python method which accepts a date input as a string.

How do I add a validation to make sure the date string being passed to the method is in the ffg. format:


if it’s not, method should raise some sort of error

Asked By: codemickeycode



The Python dateutil library is designed for this (and more). It will automatically convert this to a datetime object for you and raise a ValueError if it can’t.

As an example:

>>> from dateutil.parser import parse
>>> parse("2003-09-25")
datetime.datetime(2003, 9, 25, 0, 0)

This raises a ValueError if the date is not formatted correctly:

>>> parse("2003-09-251")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/", line 720, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/", line 317, in parse
    ret = default.replace(**repl)
ValueError: day is out of range for month

dateutil is also extremely useful if you start needing to parse other formats in the future, as it can handle most known formats intelligently and allows you to modify your specification: dateutil parsing examples.

It also handles timezones if you need that.

Update based on comments: parse also accepts the keyword argument dayfirst which controls whether the day or month is expected to come first if a date is ambiguous. This defaults to False. E.g.

>>> parse('11/12/2001')
>>> datetime.datetime(2001, 11, 12, 0, 0) # Nov 12
>>> parse('11/12/2001', dayfirst=True)
>>> datetime.datetime(2001, 12, 11, 0, 0) # Dec 11
Answered By: Jacinda
from datetime import datetime

datetime.strptime(date_string, "%Y-%m-%d")

..this raises a ValueError if it receives an incompatible format.

..if you’re dealing with dates and times a lot (in the sense of datetime objects, as opposed to unix timestamp floats), it’s a good idea to look into the pytz module, and for storage/db, store everything in UTC.

Answered By: Mr. B
>>> import datetime
>>> def validate(date_text):
        except ValueError:
            raise ValueError("Incorrect data format, should be YYYY-MM-DD")

>>> validate('2003-12-23')
>>> validate('2003-12-32')

Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
  File "<pyshell#18>", line 5, in validate
    raise ValueError("Incorrect data format, should be YYYY-MM-DD")
ValueError: Incorrect data format, should be YYYY-MM-DD

Note that obviously works only when date is in ISO format. If you need to check date in some other format, use datetime.datetime.strptime().

Answered By: jamylak

I think the full validate function should look like this:

from datetime import datetime

def validate(date_text):
        if date_text != datetime.strptime(date_text, "%Y-%m-%d").strftime('%Y-%m-%d'):
            raise ValueError
        return True
    except ValueError:
        return False

Executing just

datetime.strptime(date_text, "%Y-%m-%d") 

is not enough because strptime method doesn’t check that month and day of the month are zero-padded decimal numbers. For example

datetime.strptime("2016-5-3", '%Y-%m-%d')

will be executed without errors.

Answered By: Eduard Stepanov

From mere curiosity, I timed the two rivalling answers posted above.
And I had the following results:

dateutil.parser (valid str): 4.6732222699938575
dateutil.parser (invalid str): 1.7270505399937974
datetime.strptime (valid): 0.7822393209935399
datetime.strptime (invalid): 0.4394566189876059

And here’s the code I used (Python 3.6)

from dateutil import parser as date_parser
from datetime import datetime
from timeit import timeit

def is_date_parsing(date_str):
        return bool(date_parser.parse(date_str))
    except ValueError:
        return False

def is_date_matching(date_str):
        return bool(datetime.strptime(date_str, '%Y-%m-%d'))
    except ValueError:
        return False

if __name__ == '__main__':
    print("dateutil.parser (valid date):", end=' ')
                 setup="from __main__ import is_date_parsing",

    print("dateutil.parser (invalid date):", end=' ')
                 setup="from __main__ import is_date_parsing",

    print("datetime.strptime (valid date):", end=' ')
                 setup="from __main__ import is_date_matching",

    print("datetime.strptime (invalid date):", end=' ')
                 setup="from __main__ import is_date_matching",
Answered By: Gergely M
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.