2025年5月22日 星期四

Streamlit 學習筆記 : 使用者輸入元件 (十一) 日期選擇器

本篇旨在測試 Streamlit 的日期輸入函式 st.date_input().

本系列所有測試文章參考 :


呼叫 st.date_input() 函式並傳入必要參數 label 會建立一個日期選擇器, 其參數結構如下 : 

st.date_input(label, value=None, min_value=None, max_value=None, key=None, help=None, on_change=None, args=None, kwargs=None, disabled=False, label_visibility="visible")

st.date_input() 傳回值有兩種, 一是傳回一個 datetime.date 物件; 另一種為 (start_date, end_date) 元組, 這是當 value 傳入起迄日期元組時自動變成日期範圍選擇器. 

參數說明如下表 :


 st.date_input() 參數  說明
label 元件的標籤文字。
value 預設日期,為 datetime.datedatetime.datetime,或由 start_date/end_date 組成的日期區間。
min_value 可選的最小日期。
max_value 可選的最大日期。
key 元件的唯一識別字串,便於存取 st.session_state
help 滑鼠懸停提示文字。
on_change 當值改變時呼叫的 callback 函式。
args 傳遞給 on_change 的位置參數(tuple)。
kwargs 傳遞給 on_change 的關鍵字參數(dict)。
disabled 是否停用此元件,預設為 False
label_visibility 控制標籤的可見性,可設為 "visible""hidden""collapsed"


例如 : 


測試 1 : 預設的日期選擇器 [看原始碼] 

# st-date_input-test-1.py
import streamlit as st

selected=st.date_input('請選擇日期 :')
if selected:
    st.write(selected)

初始化時預設顯示今日日期 : 




點擊輸入框會彈出月曆, 選取日期後預設傳回一個 datetime.date 物件, 用 st.write() 輸出會以 YYYY-MM-DD 格式顯示 :





由上例可知, 若未傳入 value 參數, 日期選擇器預設顯示今日日期, 下面範例用 3 種方式傳入 value 參數來設定預選取日期 :


測試 2 : 用 value 參數設定預選取日期 [看原始碼] 

# st-date_input-test-2.py
import streamlit as st
from datetime import datetime

dt=datetime(2025, 5, 27, 0, 0)
date1=st.date_input('請選擇日期 :', key='date1', value=dt)
if date1:
    st.write(date1)
date2=st.date_input('請選擇日期 :', key='date2', value=dt.date())
if date2:
    st.write(date2)    
date3=st.date_input('請選擇日期 :', key='date3', value='2025-05-27')
if date3:
    st.write(date3)

此例使用 datetime.datetime() 函式建立指定日期 2025-05-27 的 datetime 物件, 可以直接將其傳給 value 傳回 date1; 或者呼叫其 date() 方法, 它會傳回一個 date 物件, 將其傳給 value 傳回 date2; 也可以直接將 YYYY-MM-DD 格式的日期字串傳給 value 取得 date3, 結果如下 :




參數 value 除了可用上面三種日期格式設定預先選取日期外, 也可以傳入兩個 datetime 物件組成的元組 (start_date, end_date) 來預先選取一個日期範圍, 傳回值也是 (start_date, end_date) 元組, 例如 :


測試 3 : 傳遞 datetime 元組給 value 參數設定預選取日期範圍 [看原始碼] 

# st-date_input-test-3.py
import streamlit as st
from datetime import datetime, timedelta

today=datetime.today()
start_date=today-timedelta(days=7)
end_date=today
date_range=st.date_input('請選擇日期範圍 :', value=(start_date, end_date))
if isinstance(date_range, tuple) and len(date_range) == 2:
    st.write(f'起始日期:{date_range[0]}')
    st.write(f'結束日期:{date_range[1]}')
else:
    st.write('請選擇一個日期範圍')

此例用 timedelta() 計算 7 日前的 datetime 物件為起始日期, 今日為結束日期, 將兩者組成 tuple 傳給 value 參數, 初始化時月曆上就會預先選取此日期範圍 :




點選修改日期範圍 :




傳回新的日期範圍 : 




傳遞日期字串元組給 value 也是可以的, 但這樣就無法利用 datetime.timedelta() 來計算天數了, 例如 : 


測試 4 : 傳遞日期字串元組給 value 參數設定預選取日期範圍 [看原始碼] 

# st-date_input-test-4.py
import streamlit as st
from datetime import datetime

date_range=st.date_input('請選擇日期範圍 :', value=('2025-05-04', '2025-05-30'))
if isinstance(date_range, tuple) and len(date_range) == 2:
    st.write(f'起始日期:{date_range[0]}')
    st.write(f'結束日期:{date_range[1]}')
else:
    st.write('請選擇一個日期範圍')

結果如下 :




參數 max_value 與 min_value 分別用來設定可選擇日期的範圍, 如下例所示 : 


測試 5 : 用 max_value 與 min_value 參數設定可選取日期範圍 [看原始碼] 

# st-date_input-test-5.py
import streamlit as st
from datetime import datetime

date_range=st.date_input(
    '請選擇日期範圍 :',
    min_value='2025-05-06',
    max_value='2025-05-30',
    value=('2025-05-13', '2025-05-23')
    )
if isinstance(date_range, tuple) and len(date_range) == 2:
    st.write(f'起始日期:{date_range[0]}')
    st.write(f'結束日期:{date_range[1]}')
else:
    st.write('請選擇一個日期範圍')

此例參數 max_value 與 min_value 均使用日期字串, 當然也可以用 datetime 物件來設定, 結果如下 :




由於設定可選擇日期範圍為 5/6~5/50, 所以 5/1~5/5 與 5/31 無法選取. 

下面範例測試 args 與 on_change 參數用法 :


測試 6 : 利用 args 參數攜帶引數給 on_change 事件處理函式 [看原始碼] 

# st-date_input-test-6.py
import streamlit as st

def show_birthday_msg(name):
    st.write(f'祝 {name} {st.session_state["birthday"]} 生日快樂!')

name=st.text_input('請輸入名字:', 'Tony')
st.date_input(
    '請選擇日期 :',
    key='birthday',
    on_change=show_birthday_msg,
    args=(name,)
    )

此例使用 args 將引數傳給 on_change 事件處理函式的 name 參數, 結果如下 :





上例也可以用 kwargs 來做, 例如 :


測試 7 : 利用 args 參數攜帶引數給 on_change 事件處理函式 [看原始碼] 

# st-date_input-test-7.py
import streamlit as st

def show_birthday_msg(name):
    st.write(f'祝 {name} {st.session_state["birthday"]} 生日快樂!')

name=st.text_input('請輸入名字:', 'Tony')
st.date_input(
    '請選擇日期 :',
    key='birthday',
    on_change=show_birthday_msg,
    kwargs={'name': name}
    )

結果與上面一樣. 

沒有留言 :