Blank date for st.date_input


Is it possible to start with a blank date when using the st.date_input?

Use case: when storing dates from a form / several individual date widgets to a database, even the date widgets that the user has not entered default to the current date, which gets updated into the database. Setting the parameter (value=None) does not work.

Would like a solution / hack, if possible,

Thanks in advance,


Hey @Shawn_Pereira -

Your best bet might be to use text_input in this case, and use Python to validate that it’s a valid date before writing to the database. But in general, I agree, would be great to have an ‘optional/none’ value, especially for fields like forms.


1 Like

Thanks @randyzwitch , for your prompt response. I hope Streamlit implements this functionality in the near future - it is already there for a date range, but not for single dates.


We were actually thinking about allowing None as a default value for all widgets! Great to hear that this is really needed.


this is a great idea did it become available or still on going ??

It’s not available yet. We still want to do it but there are some edge cases we need to figure out. Can’t tell you a date yet, unfortunately.

There are several ways to do this, including shorter, more complex ones (which I have yet to work on). Posting the code here in case anyone needs it. The code validates a date of a certain format (dd-mmm-yy / dd-mmm-yyyy) entered through a text_input widget. The character separators within the date can be either space, forward slash, hyphen and period. This was for my specific use case only, and anyone can repurpose it for their use.

Nevertheless, looking forward to the None option for all widgets.

The code:

def CheckDateFromTextInput(year_digits = 2):
    valid_date = True

    tdt = st.session_state.mydt
    d1 = ""     #day Eg. 12 or 3
    d2 = ""     #month Eg. Jan
    d3 = ""     #year Eg. 22 for year_digits = 2; 2022 for year_digits = 4

    if (year_digits == 2 and (len(tdt) < 8 or len(tdt) > 9)) or \
       (year_digits == 4 and (len(tdt) < 10 or len(tdt) > 11)):
        valid_date = False

    if valid_date:
        tdelimiter = ""
        if tdt.count("-") == 2:
            tdelimiter = "-" 
        elif tdt.count(".") == 2:
            tdelimiter = "."
        elif tdt.count("/") == 2:
            tdelimiter = "/"

        elif tdt.count(" ") == 2:
            tdelimiter = " "
            valid_date = False  # date does not contain delimiters

    if valid_date:
        dtarr = tdt.split(tdelimiter)
        dtarr = [x.strip() for x in dtarr]

        #day Eg. 12 or 3
        if (len(dtarr[0]) == 1 or  len(dtarr[0]) == 2) and dtarr[0].isnumeric():
            d1 = dtarr[0].zfill(2)
            valid_date = False

        #month Eg. Jan
        if len(dtarr[1]) != 3 or (dtarr[1].upper() not in ("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC")):
            valid_date = False
            d2 = dtarr[1].capitalize()

        #year Eg. 22 for year_digits = 2; 2022 for year_digits = 4
        if len(dtarr[2]) == year_digits and dtarr[2].isnumeric():
            d3 = dtarr[2].zfill(year_digits)

            valid_date = False

    if not valid_date:
        st.error("Invalid date...")
        st.session_state.mydt = f"{d1}-{d2}-{d3}"

# for 2-digit year, use...
mydt = st.text_input("Enter Date (dd-mmm-yy)", placeholder="Eg. 12-Apr-22", key="mydt", on_change=CheckDateFromTextInput)

# for 4-digit year, use...
# mydt = st.text_input("Enter Date (dd-mmm-yyyy)", placeholder="Eg. 12-Apr-2022", key="mydt", on_change=CheckDateFromTextInput, args=(4,))

st.write(f"Your date is: {mydt}")


1 Like

I am creating a query interface where the user can optionally scope the search with a start and/or an end date, but not having a way to return blank or None date makes it difficult.

1 Like

+1 for allowing default=None, desperately needed