
Ant Design DatePicker 实战用 disabledDate 与 disabledTime 精准禁用日期和时间【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design本文基于 ant-design 仓库中 components/date-picker/demo/disabled-date.md 示例及其配套源码撰写讲透DatePicker中disabledDate与disabledTime两个属性如何分别禁止选择部分日期和时间。读完你将掌握如何在单日期、月份、范围选择器中禁用指定日期如何在showTime下按小时/分钟/秒粒度禁用时间以及 RangePicker 中为 start/end 两端配置不同时间禁用的完整方案并了解这些属性在源码中的类型定义与落地机制。核心能力速览原始示例文档给出的核心结论是可用disabledDate和disabledTime分别禁止选择部分日期和时间其中disabledTime需要和showTime一起使用。两个属性分工明确属性作用生效前提可禁用粒度disabledDate禁止选择指定日期无所有 picker 类型均适用天week 为周、month 为月、quarter 为季度、year 为年disabledTime禁止选择指定时间必须配合showTime使用时 / 分 / 秒从 components/date-picker/index.zh-CN.md 的 API 表可以看到二者的精确类型签名DatePicker 的disabledDate(currentDate: dayjs, info: { from?: dayjs }) boolean返回true表示该日期不可选info参数自 5.14.0 起提供DatePicker 的disabledTimefunction(date)返回包含disabledHours/disabledMinutes/disabledSeconds等函数对象的对象RangePicker 的disabledDate与 DatePicker 相同签名RangePicker 的disabledTimefunction(date: dayjs, partial: start | end, info: { from?: dayjs })——多出的partial参数正是实现「起止两端不同禁用规则」的关键info.from自 5.17.0 起提供。完整示例覆盖四种典型场景官方示例 components/date-picker/demo/disabled-date.tsx 在一个Space中并列演示了四种形态以下按原样完整给出这是可直接复制运行的完整代码import React from react; import { DatePicker, Space } from antd; import type { GetProps } from antd; import dayjs from dayjs; import customParseFormat from dayjs/plugin/customParseFormat; type RangePickerProps GetPropstypeof DatePicker.RangePicker; dayjs.extend(customParseFormat); const { RangePicker } DatePicker; const range (start: number, end: number) { const result []; for (let i start; i end; i) { result.push(i); } return result; }; // eslint-disable-next-line arrow-body-style const disabledDate: RangePickerProps[disabledDate] (current) { // Can not select days before today and today return current current dayjs().endOf(day); }; const disabledDateTime () ({ disabledHours: () range(0, 24).splice(4, 20), disabledMinutes: () range(30, 60), disabledSeconds: () [55, 56], }); const disabledRangeTime: RangePickerProps[disabledTime] (_, type) { if (type start) { return { disabledHours: () range(0, 60).splice(4, 20), disabledMinutes: () range(30, 60), disabledSeconds: () [55, 56], }; } return { disabledHours: () range(0, 60).splice(20, 4), disabledMinutes: () range(0, 31), disabledSeconds: () [55, 56], }; }; const App: React.FC () ( Space directionvertical size{12} DatePicker formatYYYY-MM-DD HH:mm:ss disabledDate{disabledDate} disabledTime{disabledDateTime} showTime{{ defaultValue: dayjs(00:00:00, HH:mm:ss) }} / DatePicker pickermonth disabledDate{disabledDate} / RangePicker disabledDate{disabledDate} / RangePicker disabledDate{disabledDate} disabledTime{disabledRangeTime} showTime{{ hideDisabledOptions: true, defaultValue: [dayjs(00:00:00, HH:mm:ss), dayjs(11:59:59, HH:mm:ss)], }} formatYYYY-MM-DD HH:mm:ss / /Space ); export default App;四个控件各自展示了不同的禁用策略组合值得逐一拆解。场景一单日期选择器 —— 日期 时间双重禁用第一个DatePicker同时使用了disabledDate与disabledTime并设置了showTime。其中formatYYYY-MM-DD HH:mm:ss开启时间列后展示完整时间showTime{{ defaultValue: dayjs(00:00:00, HH:mm:ss) }}通过defaultValue固定时间列的初始值。文档 components/date-picker/index.zh-CN.md 中showTime.defaultValue一栏明确注明了默认时分秒的取值——DatePicker 默认为dayjs()RangePicker 默认为[dayjs(), dayjs()]此处将其显式钉在00:00:00避免每次打开面板时分秒都是当前时刻便于测试与展示。disabledDate的实现是业务中最常用的「禁止选择今天及更早的日期」模式const disabledDate: RangePickerProps[disabledDate] (current) { // Can not select days before today and today return current current dayjs().endOf(day); };current dayjs().endOf(day)的写法很关键endOf(day)把「今天」归一化到当天23:59:59.999因此判断current 今天 23:59:59.999意味着今天一整天都被禁用如果想保留今天可选应改为current.isBefore(dayjs(), day)。返回表达式前缀的current 是防御性写法——current为null/undefined时不抛出直接判为可选。disabledDateTime返回三个禁用函数逐项拆解如下const disabledDateTime () ({ disabledHours: () range(0, 24).splice(4, 20), // [0..23] 从索引 4 起删除 20 个 禁用 4~23 时 disabledMinutes: () range(30, 60), // 禁用 30~59 分 disabledSeconds: () [55, 56], // 禁用 55、56 秒 });这里有一个容易被忽略的 JS 细节range(0, 24).splice(4, 20)中splice是原地修改并返回被删除的片段所以返回[4, 5, ..., 23]即 4 点到 23 点全部禁用0~3 时可选。三个禁用函数都声明为返回数组的函数而非直接返回数组这是 rc-picker 的约定——函数形式使得禁用规则可以在面板滚动、切换时按需惰性求值。场景二月份选择器 —— disabledDate 粒度随 picker 变化DatePicker pickermonth disabledDate{disabledDate} /同一个disabledDate函数无需任何修改即可作用于月份面板。这是因为面板渲染时传给disabledDate的currentDate粒度与 picker 类型一致month 模式下为当月 1 日的 dayjs 对象。从源码结构看disabledDate并不由 antd 自行解释而是作为 prop 透传给底层的 rc-picker 面板组件由各面板日/月/年/季度在生成单元格时调用判断因此「同一函数适配不同粒度」是自然成立的行为。值得注意的是月份选择器只传了disabledDate没有showTime这再次印证了disabledTime依赖showTime才能生效的约束——没有时间列禁用时间也无从谈起。场景三RangePicker —— 仅禁用日期的最简形态RangePicker disabledDate{disabledDate} /范围选择器同样直接复用disabledDate禁用今天及之前的所有日期。disabledDate是 DatePicker 与 RangePicker 共享的共同 API见 components/date-picker/index.zh-CN.md 「共同的 API」小节因此在两种组件间迁移禁用规则零成本。场景四RangePicker showTime —— 起止两端差异化禁用这是示例中最复杂的组合也是disabledTime类型签名中partial参数的实战体现RangePicker disabledDate{disabledDate} disabledTime{disabledRangeTime} showTime{{ hideDisabledOptions: true, defaultValue: [dayjs(00:00:00, HH:mm:ss), dayjs(11:59:59, HH:mm:ss)], }} formatYYYY-MM-DD HH:mm:ss /disabledRangeTime利用第二个参数type即start | end为两端返回不同的禁用对象禁用项start 端开始时间end 端结束时间disabledHoursrange(0, 60).splice(4, 20)→ 4~23 时range(0, 60).splice(20, 4)→ 20~23 时disabledMinutesrange(30, 60)→ 30~59 分range(0, 31)→ 0~30 分disabledSeconds[55, 56][55, 56]注意这里range(0, 60)生成了 0~59 的数组再取片段——超出 23 的「小时」值在面板中本就不存在不会造成副作用但splice(20, 4)恰好取到[20, 21, 22, 23]四个小时。这种写法构造了一个现实业务中很常见的约束形态开始时间只能选早段、结束时间只能选晚段天然形成「早 4 点开门、晚 11 点关门」之类的营业时段逻辑。另外两个showTime选项也值得说明hideDisabledOptions: true隐藏被禁用的时间选项而不是灰显。该选项属于 TimePicker 选项集见 components/time-picker/index.zh-CN.md API 表中的hideDisabledOptions「隐藏禁止选择的选项」默认false通过showTime对象传入即可defaultValueRangePicker 场景下是二元数组分别指定起止两端时间列的初始时分秒示例中起点为00:00:00、终点为11:59:59。前置依赖dayjs 的 customParseFormat 插件示例开头有一行看似不起眼的代码import customParseFormat from dayjs/plugin/customParseFormat; dayjs.extend(customParseFormat);其作用是让dayjs(00:00:00, HH:mm:ss)这类带显式格式字符串解析短格式的调用成为可能。原生 dayjs 只在 ISO 格式下支持第二参数格式短格式如HH:mm:ss必须依赖customParseFormat插件否则解析可能回退为Invalid Date。只要你在业务中使用showTime.defaultValue传入HH:mm:ss形态的 dayjs就应当确保该插件已注册——这也是官方示例将其写在文件顶部的原因。源码机制disabledDate / disabledTime 如何落地从源码结构看antd 的日期组件是 rc-picker 的轻量封装禁用逻辑的完整执行发生在 rc-picker 内部antd 只负责属性透传与类型增强入口组装components/date-picker/index.tsx 中通过generatePicker(dayjsGenerateConfig)生成整套 picker 组件族DatePicker、RangePicker、MonthPicker 等见 components/date-picker/generatePicker/index.tsx它分别调用generateSinglePicker与generateRangePicker属性透传在 components/date-picker/generatePicker/generateSinglePicker.tsx 中antd 把props解构出需要覆写的部分prefixCls、placement、locale、zIndex 等其余全部通过{...restProps}原样展开到RCPicker上——disabledDate与disabledTime就属于这批被透传的 propantd 层不对其做任何改写类型增强components/date-picker/generatePicker/interface.ts 中PickerProps由 rc-picker 的PickerProps经过InjectDefaultProps注入 antd 自有属性size、placement、variant等构成disabledDate/disabledTime的函数签名则继承自 rc-picker 的类型定义与 components/date-picker/index.zh-CN.md 中 API 表列出的签名一致测试佐证components/date-picker/tests/DatePicker.test.tsx 中包含针对disabledDate的用例覆盖「按回调禁用日期」的渲染行为。因此可以推断如果你在自定义components5.14.0 起支持的自定义面板或cellRender5.4.0 起时调整了单元格结构只要没有破坏 rc-picker 面板对disabledDate的调用链禁用逻辑依然由底层统一驱动无需在自定义渲染中重复实现判断。实战要点与常见陷阱结合示例与 API 文档落地时有几个高频注意点disabledTime单独使用无效。必须同时设置showTimetrue或对象否则时间列不渲染禁用规则无处生效。这是原始示例文档强调的第一句话也是排障时第一件要检查的事禁用函数返回的是 dayjs 比较结果判断「小于」而非「不等于」能覆盖整段区间。例如禁止选择某日之前全部日期current dayjs(2025-01-01)disabledDate的返回值语义是「true 即禁用」与直觉相反不是返回可选日期写反后会导致整个面板全部不可点排查时先打印返回值确认RangePicker 的disabledTime签名多一个partial参数写单日期版本的disabledTime函数到 RangePicker 上不会报错多余参数被忽略但会失去两端差异化能力——建议像示例中disabledRangeTime(_, type)那样显式声明并使用typeshowTime.defaultValue配合customParseFormat插件注册短格式解析避免Invalid Date与multiple互斥API 文档明确multiple5.14.0 多选不支持showTime因此多选场景天然无法使用disabledTime只能靠disabledDate做粒度控制5.14.0 的minDate/maxDate可作为更声明式的替代方案「最小/最大日期同样会限制面板的切换范围」。如果你的需求只是「限制一个区间边界」用minDate/maxDate比手写disabledDate更简洁只有当禁用规则是非区间形态如「禁周末」「禁 4~23 时」时才需要回调函数。小结disabledDate与disabledTime是 ant-design DatePicker 家族控制可选项的两大开关前者按日期粒度、跨 DatePicker/RangePicker 通用后者按时分秒粒度、必须挂载在showTime之下且在 RangePicker 中通过partial参数区分起止两端。官方示例 components/date-picker/demo/disabled-date.tsx 用四个控件覆盖了「单日期双禁用、月份粒度、纯范围、范围差异化时间」的典型组合配合showTime.defaultValue与hideDisabledOptions即可满足绝大多数排班、预约、营业时段类的日期录入场景。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考