Home » Python » How do I validate a date string format in python?

How do I validate a date string format in python?

Posted by: admin November 29, 2017 Leave a comment

Questions:

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:

'YYYY-MM-DD'

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

Answers:
>>> import datetime
>>> def validate(date_text):
    try:
        datetime.datetime.strptime(date_text, '%Y-%m-%d')
    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>
    validate('2003-12-32')
  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

Questions:
Answers:

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/parser.py", line 720, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/parser.py", 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

Questions:
Answers:
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.

Questions:
Answers:

I think the full validate function should look like this:

from datetime import datetime

def validate(date_text):
    try:
        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.

Questions:
Answers:

This is the easiest way:

date = datetime.now()
date = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')