跳到主要内容

DatePicker 选择范围限制问题

前言

在 Antd 5.14 之后,DatePicker 新增了 minDatemaxDate 参数,用于限制日期选择。然而,当 DatePicker 开启 showTime 时,限制具体时间需要自行实现。 那么我将说一下 disabledDatedisabledTime 使用, 来实现日期和时间的选择限制。

原理

Antd 的 DatePicker 提供了 disabledDatedisabledTime 参数。

disabledDate

disabledDate 参数用于限制日期选择。只需返回 truefalse 即可,逻辑简单明了。

disabledTime

disabledTime 参数用于限制时间选择。它需要返回一个对象,包括 disabledHoursdisabledMinutesdisabledSeconds 三个属性,分别表示禁用的小时、分钟和秒数。

示例

假设需要禁用以下时间段:

  • 小时: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],
};

通过将需要禁用的时间放入对应的数组中,可以灵活地实现时间选择的限制。

通过合理使用 disabledDatedisabledTime,可以实现对 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

试一试