DatePicker 选择范围限制问题
前言
在 Antd 5.14 之后,DatePicker 新增了 minDate
和 maxDate
参数,用于限制日期选择。然而,当 DatePicker 开启 showTime
时,限制具体时间需要自行实现。
那么我将说一下 disabledDate
和 disabledTime
使用, 来实现日期和时间的选择限制。
原理
Antd 的 DatePicker 提供了 disabledDate
和 disabledTime
参数。
disabledDate
disabledDate
参数用于限制日期选择。只需返回 true
或 false
即可,逻辑简单明了。
disabledTime
disabledTime
参数用于限制时间选择。它需要返回一个对象,包括 disabledHours
、disabledMinutes
和 disabledSeconds
三个属性,分别表示禁用的小时、分钟和秒数。
示例
假设需要禁用以下时间段:
- 小时:4, 5, 6, 10
- 分钟:10-20, 25-30, 40, 55
- 秒:1-10, 34, 56
disabledTime
的返回值如下:
return {
disabledHours: [4, 5, 6, 10],
disabledMinutes: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 40, 55],
disabledSeconds: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 34, 56],
};
通过将需要禁用的时间放入对应的数组中,可以灵活地实现时间选择的限制。
通过合理使用 disabledDate
和 disabledTime
,可以实现对 DatePicker 的日期和时间选 择进行精确的控制,满足不同场景的需求。
实现两个时间选择器互相限制选择范围
需求
- 第一个时间选择器(startTime)选择后,第二个时间选择器(endTime)不能选择其之前的时间
- 第二个时间选择器(endTime)选择后,第一个时间选择器(startTime)不能选择其之后的时间
- 结束时间不超过当前时间
代码实现
import { useState } from 'react'
import { DatePicker, Form } from 'antd'
import dayjs from 'dayjs'
const DatepickerDemo = () => {
const [startTime, setStartTime] = useState<any>() //起始时间值
const [endTime, setEndTime] = useState<any>() // 结束时间值
const [arr23] = useState<any>(Array.from({ length: 24 }, (v, k) => k))
const [arr59] = useState<any>(Array.from({ length: 60 }, (v, k) => k))
return <>
<Form >
<Form.Item label='起始时间' name='startTime'>
<DatePicker
placeholder='请选择时间'
showTime
value={startTime}
onChange={(e: any) => {
setStartTime(e)
}}
disabledDate={(current: any) => {
if (current && endTime) {
return current && current > endTime
}
else {
return current && current > dayjs()
}
}}
disabledTime={(current: any) => {
let disabledHours = (): number[] => { return [] },
disabledMinutes = (): number[] => { return [] },
disabledSeconds = (): number[] => { return [] }
const currentEndTime = endTime || dayjs() //如果有结束时间 ,以结束时间作为限制 ,否则以当前时间作为限制
if (current?.format('YYYY-MM-DD') == currentEndTime?.format('YYYY-MM-DD')) { //是当前天,限制小时
disabledHours = () => {
const hours = arr23.filter((item) => {
return item > Number(currentEndTime?.format('HH'))
})
return hours
}
if (current?.format('HH') == currentEndTime?.format('HH')) { // 是当前天下的当前小时,限制分钟
disabledMinutes = () => {
const minutes = arr59.filter((item) => {
return item > Number(currentEndTime?.format('mm'))
})
return minutes
}
if (current?.format('mm') == currentEndTime?.format('mm')) { // 是当前天下的当前小时的当前分钟,限制秒
disabledSeconds = () => {
const seconds = arr59.filter((item) => {
return item > Number(currentEndTime?.format('ss'))
})
return seconds
}
}
}
}
return { disabledHours, disabledMinutes, disabledSeconds }
}}
/>
</Form.Item>
<Form.Item label='结束时间' name='endTime'>
<DatePicker
placeholder='请选择时间'
showTime
value={endTime}
disabledDate={(current: any) => {
if (current && startTime) {
return current < startTime.add(1, 'second').subtract(1, 'day') || current > dayjs()
} else {
return current && current > dayjs()
}
}}
disabledTime={(current: any) => {
let disabledHours = (): number[] => { return [] },
disabledMinutes = (): number[] => { return [] },
disabledSeconds = (): number[] => { return [] }
const currentStartTime = startTime || dayjs() //如果起始时间 ,以起始时间作为限制 ,否则不限制
const currentEndTime = dayjs() //结束时间为当前时间
const inStartDay: boolean = current?.format('YYYY-MM-DD') == currentStartTime?.format('YYYY-MM-DD')
const inEndDay: boolean = current?.format('YYYY-MM-DD') == currentEndTime?.format('YYYY-MM-DD')
const inOneDay: boolean = inStartDay && inEndDay
if (inOneDay) {
disabledHours = () => {
const hours = arr23.filter((item) => {
return item > Number(currentEndTime?.format('HH')) || item < Number(currentStartTime?.format('HH'))
})
return hours
}
if (current?.format('HH') == currentEndTime.format('HH')) { // 是当前天下的当前小时,限制分钟
disabledMinutes = () => {
const minutes = arr59.filter((item) => {
return item > Number(currentEndTime?.format('mm')) || item < Number(currentStartTime?.format('mm'))
})
return minutes
}
if (current?.format('mm') == currentEndTime.format('mm')) { // 是当前天下的当前小时的当前分钟,限制秒
disabledSeconds = () => {
const seconds = arr59.filter((item) => {
return item > Number(currentEndTime?.format('ss')) || item < Number(currentStartTime?.format('ss'))
})
return seconds
}
}
}
} else if (inStartDay) {
disabledHours = () => {
const hours = arr23.filter((item) => {
return item < Number(currentStartTime?.format('HH'))
})
return hours
}
if (current?.format('HH') == currentStartTime?.format('HH')) { // 是当前天下的当前小时,限制分钟
disabledMinutes = () => {
const minutes = arr59.filter((item) => {
return item < Number(currentStartTime?.format('mm'))
})
return minutes
}
if (current?.format('mm') == currentStartTime?.format('mm')) { // 是当前天下的当前小时的当前分钟,限制秒
disabledSeconds = () => {
const seconds = arr59.filter((item) => {
return item < Number(currentStartTime?.format('ss'))
})
return seconds
}
}
}
} else if (inEndDay) {
disabledHours = () => {
const hours = arr23.filter((item) => {
return item > Number(currentEndTime?.format('HH'))
})
return hours
}
if (current?.format('HH') == currentEndTime?.format('HH')) { // 是当前天下的当前小时,限制分钟
disabledMinutes = () => {
const minutes = arr59.filter((item) => {
return item > Number(currentEndTime?.format('mm'))
})
return minutes
}
if (current?.format('mm') == currentEndTime?.format('mm')) { // 是当前天下的当前小时的当前分钟,限制秒
disabledSeconds = () => {
const seconds = arr59.filter((item) => {
return item > Number(endTime?.format('ss'))
})
return seconds
}
}
}
}
return { disabledHours, disabledMinutes, disabledSeconds }
}}
onChange={(e: any) => {
setEndTime(e)
}}
/>
</Form.Item>
</Form >
</>
}
export default DatepickerDemo