Using st.date_input to get multiple dates input with one st.date_input call?

With the following code, I want to get the start and end date input.

start, end = st.date_input(label='Date Range: ',
              value=(datetime.datetime(year=2022, month=5, day=20, hour=16, minute=30), 
                     datetime.datetime(year=2022, month=5, day=30, hour=16, minute=30)),
              key='#date_range',
              help="The start and end date time",
              on_change=lambda : st.write("Start and end date time set!"))
st.write('Start: ', start, "End: ", end)

When prompted, the user clicks on the calendar, there is an error message:

ValueError: not enough values to unpack (expected 2, got 1)

What’s the proper way to get two dates entered? From the documentation st.date_input - Streamlit Docs
it sounds possible to get a tuple of dates.

The alternative works with single item input by one call, but less compact:

start = st.date_input(label='Start: ',
              value=datetime.datetime(year=2022, month=5, day=20, hour=16, minute=30),
              key='#start',
              help="The start date time",
                      on_change=lambda : None)

end = st.date_input(label='End: ',
              value=datetime.datetime(year=2022, month=5, day=30, hour=16, minute=30),
              key='#end',
              help="The end date time",
                    on_change=lambda : None)
st.write('Start: ', start, "End: ", end)

Hi @Yu_Shen , the problem is that your date input returns an array instead of 2 variables (start and end). You can access the returned (single) variable using the indices of 0 & 1 for the start date & end date. For your testing, the code is below:

from datetime import datetime as dt
try:
    dts = st.date_input(label='Date Range: ',
                value=(dt(year=2022, month=5, day=20, hour=16, minute=30), 
                        dt(year=2022, month=5, day=30, hour=16, minute=30)),
                key='#date_range',
                help="The start and end date time")
    st.write('Start: ', dts[0], "End: ", dts[1])

except:
    pass

Cheers

1 Like

Thanks! Indeed your example works.

But I find it strange, that usually Python support deconstruction of tuple and list.
st.date_input returns dts, a tuple. But accessing dts before st.write via deconstruction,
start, end = dts
still failed.
even
start, end = dts[0], dts[1] would fail.
Furthermore, I checked before calling st.write, the length of dts is just 1.

It seems that the behavior of support multiple inputs depends on streamlit’s own implementation, that only accessing through streamlit’s own methods, the dts is valid for multiple inputs.
For example, I observed that only access dts with st.write, then Streamlit gives me the opportunity to enter two inputs, rather than completes the input with just one input.

So the moral of my story may be that accessing st.date_input for multiple inputs can only be done within the context of Streamlit methods.

By the way, st.date_input can only support input date, without time (hour, minute).
I wish to have a single mechanism to input both date and time.
(I may use st.date_input, and st.time_input in combination. But then I need to learn how to arrange the layout with st so that the prompts of input date, and time can be combined to be clear in the UI)