首页
/ Ant Design DatePicker 禁用不可选日期与时间:`disabledDate` 与 `disabledTime` 完整实战指南

Ant Design DatePicker 禁用不可选日期与时间:`disabledDate` 与 `disabledTime` 完整实战指南

2026-09-07 22:33:04作者:邓越浪Henry

本文围绕 Ant Design(antd)DatePicker / RangePicker 组件中“禁用不可选日期与时间”这一高频业务场景展开:通过 disabledDatedisabledTime 两个回调精准控制可选范围,覆盖单日期选择、picker="month" 月份面板、以及 RangePicker 起止时间分别禁用的完整写法。文章以官方 Demo disabled-date 及其完整实现 disabled-date.tsx 为主线,并对照仓库中的类型定义与单元测试,帮助读者彻底掌握这套“日期 + 时间”双重禁用方案,直接落地到自己的业务表单中。

一、核心 API 语义:三件事先说清楚

在动手写代码前,先明确 Demo 描述中隐含的三个前提(原文见 disabled-date.md):

  1. disabledDate 用于禁用日期(天/月/年等单元格),它是 DatePicker、RangePicker、TimePicker 之外所有 picker 模式的通用能力;
  2. disabledTime 用于禁用时间(时/分/秒),它只在日期选择器开启了 showTime 时才生效——文档明确指出 “disabledTime only works with showTime”,没有 showTime 就不会渲染时间选择面板,禁用时间自然无从谈起;
  3. 二者可以单独使用,也可以叠加使用disabledDate 限制日期、disabledTime 限制该日期的可选时刻),从而形成“某天可选但只能选某几个时段”这样的精细控制。

从 API 文档 index.en-US.md 可以看到 disabledDate 的完整签名:

disabledDate?: (currentDate: dayjs, info: { from?: dayjs; type: Picker }) => boolean
  • 返回值语义:返回 true(或任意 truthy 值)表示当前单元格不可选,会被置灰并阻止点击;返回 false 表示可选。
  • currentDate:当前被判断的单元格对应的 dayjs 对象,是整个判断的核心输入。
  • info 对象5.14.0 起提供):其中 type 指当前面板模式(date / month / year / decade 等),from 在范围选择场景下指向已选中的另一端日期,可用于实现“结束不能早于开始”这类联动约束。

disabledTime 返回一个包含三个禁用函数(disabledHoursdisabledMinutesdisabledSeconds)的对象,后文会逐一演示。

二、最小可用示例:禁止今天之前(含今天)

最经典的业务规则是“不允许选择过去的日期”。官方 Demo 的第一个场景正好演示了这一写法,其完整实现位于 disabled-date.tsx

const disabledDate: RangePickerProps['disabledDate'] = (current) => {
  // Can not select days before today and today
  return current && current < dayjs().endOf('day');
};

使用方式:

<DatePicker
  format="YYYY-MM-DD HH:mm:ss"
  disabledDate={disabledDate}
  disabledTime={disabledDateTime}
  showTime={{ defaultOpenValue: dayjs('00:00:00', 'HH:mm:ss') }}
/>

这里有两个值得展开的细节:

  • 为什么用 endOf('day') 而不是直接 dayjs() 注释明确写着“禁止今天及今天以前”。若写成 current < dayjs(),由于比较的是毫秒时间戳,今天 0 点的单元格会小于“代码执行那一刻”的时间戳而被误伤;而 current < dayjs().endOf('day') 是把今天的结束时刻(23:59:59.999)作为边界,即今天整天也一并禁用。反之,若只想禁止“今天之前、今天仍可选”,应改为 current && current < dayjs().startOf('day')
  • 为什么要判断 current 本身? 面板中可能传入空值或边界值,current && 的短路写法避免了对空值做比较而产生误禁用。返回值需要兼容 null 的情况(此时应视为可选)。

仅禁止过去月份:切换 picker 模式

禁用逻辑与面板粒度强相关。disabledDate 的判断单位会随 picker 改变——当使用 picker="month" 时,currentDate 代表的是当月,因此判断边界也要换成月份粒度(同文件 disabled-date.tsx):

const disabledDateForMonth: RangePickerProps['disabledDate'] = (current) => {
  // Can not select months before this month
  return current && current < dayjs().startOf('month');
};

对比可看出:在日粒度下用 endOf('day'),在月粒度下用 startOf('month'),核心思路都是“把当前展示单元格(日/月)作为一个整体来判定是否早于允许的最早值”。

三、精确到时分秒:disabledTime + showTime

日期禁用到“天”往往不够。当业务要求“本周不可选”“9:00–17:00 之外不可约”时,就需要在 disabledDate 放行的日期内,进一步裁剪可选的时刻。此时开启 showTime 并配置 disabledTime(同文件 disabled-date.tsx):

const disabledDateTime = () => ({
  disabledHours: () => range(0, 24).splice(4, 20),
  disabledMinutes: () => range(30, 60),
  disabledSeconds: () => [55, 56],
});

其中 range(start, end) 是官方 Demo 里自己封装的生成 [start, start+1, ..., end-1] 的辅助函数。我们拆开看每个字段做了什么:

返回值字段 含义 本示例效果
disabledHours: () => number[] 返回被禁用的小时列表 range(0, 24).splice(4, 20) = [4, 5, ..., 23],即只允许 0–3 点
disabledMinutes: () => number[] 返回被禁用的分钟列表 range(30, 60) = [30, 31, ..., 59],即前半小时可选
disabledSeconds: () => number[] 返回被禁用的列表 [55, 56],其余秒均可选

注意到 disabledDateTime 是一个无参函数,因为它对所有日期一视同仁。日期选择器 API 表格(index.en-US.md)中 disabledTime 的签名为 function(date)——如果你需要“不同日期可用的时间不同”,就可以接收 date 参数按日期分支处理。

配套设置 showTime.defaultOpenValue:由于很多时段被禁用,如果直接打开时间面板可能没有可聚焦的默认值,导致选中日期后时间部分为空。Demo 中通过 showTime={{ defaultOpenValue: dayjs('00:00:00', 'HH:mm:ss') }} 显式指定面板展开时默认选中的时间,同时外层 format="YYYY-MM-DD HH:mm:ss" 让输入框能展示完整的日期时间。该写法同样出现在官方 API 说明中被点名引用(showTime.defaultOpenValue 一栏的示例链接正是 #date-picker-demo-disabled-date)。

四、RangePicker:起止时间分别禁用

范围选择是 disabledDate/disabledTime 发挥最大价值的场景——起止两端往往需要不同的时间约束。先看纯日期版,只禁过去日期:

<RangePicker disabledDate={disabledDate} />

再看“起止时间分别禁用”的进阶版(disabled-date.tsx):

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],
  };
};

对应的组件写法:

<RangePicker
  disabledDate={disabledDate}
  disabledTime={disabledRangeTime}
  showTime={{
    hideDisabledOptions: true,
    defaultOpenValue: [dayjs('00:00:00', 'HH:mm:ss'), dayjs('11:59:59', 'HH:mm:ss')],
  }}
  format="YYYY-MM-DD HH:mm:ss"
/>

与单日期版本的关键差异:

  1. 回调多了第二个参数 type。RangePicker 的 disabledTime 签名为 function(date: dayjs, partial: 'start' | 'end', info: { from?: dayjs })(见 index.en-US.md),partial 告诉你当前正在配置的是起点还是终点info.from5.17.0 起提供,指向另一端已选日期,可用于实现“结束日当天只能选比开始时刻晚的时间”这类联动。
  2. 起止的策略在本例中是对称的:起点允许 0–3 点的早间时段,终点允许 20–23 点的晚间时段,配合外层 disabledDate(禁过去日期),模拟出“早出发 / 晚返回”的业务直觉。
  3. showTime.hideDisabledOptions:置为 true 后,被禁用的时/分/秒选项会直接从下拉列表中隐藏而不是灰色展示,UI 更干净,适合禁用项很多的场景;保持默认 false 则灰显,能让用户感知存在但不可用的时段。
  4. defaultOpenValue 变成了二元数组:分别对应起点和终点面板的默认打开时刻 [00:00:00, 11:59:59],这正是 API 文档 index.en-US.mdshowTime.defaultOpenValue 的 RangePicker 形态。

五、源码视角:这两个 Props 从哪来、如何生效

作为生成式组件的产物,DatePicker / RangePicker 的 Props 最终来自 @rc-component/pickerRcPickerProps / RcRangePickerProps。在 generatePicker/interface.ts 中可以看到:

export type PickerProps<DateType extends AnyObject = any> = InjectDefaultProps<
  RcPickerProps<DateType>
>;

export type RangePickerProps<DateType extends AnyObject = any> = InjectDefaultProps<
  RcRangePickerProps<DateType>
>;

disabledDatedisabledTimeshowTime 等能力均由底层 @rc-component/picker 实现,antd 通过 InjectDefaultProps 在类型层面注入 localeplacementvariantclassNames/styles 等 antd 语义化封装,因此你在业务代码中通过 GetProps<typeof DatePicker.RangePicker> 取出的 Props 类型(Demo 第 7 行的 RangePickerProps)天然带全这些字段的精确签名与 dayjs 泛型推导。关于单元格禁用的具体交互(置灰、阻止点击、键盘导航跳过),都发生在该底层选择器包的日期面板内部,antd 层负责把回调透传下去。

这一行为的正确性在仓库测试中有直接印证。DatePicker.test.tsx 中就有一个与本文完全同构的用例:

const disabledDate = (current: any) => current && current < dayjs().endOf('day');
render(<DatePicker disabledDate={disabledDate} open />);

它用 endOf('day') 的判定方式构造禁用日期并渲染面板,验证日期格子的禁用与不可点选行为,说明“禁止今天及更早日期”是 antd 官方认可的标准写法,你可以放心在生产代码中复用。

六、API 速查与注意事项

参数速查

参数 作用 类型 可用组件 版本备注
disabledDate 指定不可选择的日期(单元格粒度随 picker 变化) (currentDate: dayjs, info: { from?: dayjs, type: Picker }) => boolean DatePicker / RangePicker info 参数自 5.14.0 提供
disabledTime 指定不可选择的时间,须与 showTime 搭配 DatePicker:function(date);RangePicker:function(date: dayjs, partial: 'start' | 'end', info: { from?: dayjs }) DatePicker / RangePicker(开启 showTime 时) RangePicker 的 info.from5.17.0 提供
showTime.hideDisabledOptions 隐藏(true)或灰显(默认 false)被禁用的时分秒选项 boolean 二者
showTime.defaultOpenValue 打开时间面板时的默认选中时刻;RangePicker 传二元数组 dayjs | [dayjs, dayjs] 二者 取代已废弃的 showTime.defaultValue

实践要点清单

  1. 边界值用粒度匹配的 startOf/endOf:禁“今天及以前”用 current < dayjs().endOf('day');禁“本月及以前”用 current < dayjs().startOf('month');不同 picker 粒度要换对应的比较单位。
  2. disabledTime 离不开 showTime:不加 showTime 时传入 disabledTime 不会生效(无时间面板可操作)。
  3. RangePicker 务必利用 partial: 'start' | 'end' 区分两端,否则两端会套用同一套时间禁用规则;更复杂的“结束时间不能早于开始时间”联动可读取 info.from
  4. 配合 formatdefaultOpenValue:一旦约束到时分秒,建议把 format 扩为 "YYYY-MM-DD HH:mm:ss",并通过 defaultOpenValue 给时间面板一个合法默认值,避免“日期可选但时间无可选默认项”的空白态。
  5. 纯禁用需求的轻量替代:若只是禁止“某一天之前/之后”,5.14.0 起还可用 minDate / maxDate(见 index.en-US.md);但当禁用规则是“非连续的若干天/特定星期几/排除节假日”这类任意逻辑时,函数式 disabledDate 仍是唯一通用的方案。
  6. 从完整示例起步:本文所有代码均取自可直接运行的官方 Demo disabled-date.tsx,它同时覆盖了单日期、月份面板、RangePicker 日期、RangePicker 日期+时间四种形态,是复刻到业务代码的最佳模板。配套的更多用法(时间选择、区间联动、禁止整组件)可进一步参考同目录下的 time.mdrange-picker.mddisabled.md 等 Demo。

掌握 disabledDatedisabledTime 的组合用法后,无论是“仅可选未来 30 天”“工作日可选”“历史日期仅早班可约”还是“RangePicker 起止时间错峰”等真实业务约束,都可以用声明式回调在几分钟内稳定实现,而不必在提交前做二次表单校验来兜底。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525