news 2026/9/21 17:14:36

Handsontable 时间单元格类型(Time Cell Type)完整指南:基于 Intl.DateTimeFormat 的时间格式化、校验与编辑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Handsontable 时间单元格类型(Time Cell Type)完整指南:基于 Intl.DateTimeFormat 的时间格式化、校验与编辑

Handsontable 时间单元格类型(Time Cell Type)完整指南:基于 Intl.DateTimeFormat 的时间格式化、校验与编辑

【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look & Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable

本指南围绕 Handsontable 官方文档 time-cell-type.md 展开,结合仓库内handsontable/src/cellTypes/intlTimeTypetimeType的源码实现与示例代码,系统讲解如何用intl-time/time单元格类型展示、格式化、校验、编辑、排序与过滤时间值。

Handsontable 的intl-timetime单元格类型(cell type)用于把单元格值当作时间来处理:通过可配置的格式字符串控制显示样式,并校验用户输入。它基于浏览器原生的Intl.DateTimeFormatAPI,适用于排班(scheduling)、日志(logging)或任何基于时间的数据场景。阅读本文后,你将掌握:在整表、单列或单单元格上配置时间单元格类型;使用timeFormat对象定制显示格式与 locale;理解源码层的数据格式约束与校验逻辑;以及时间值在排序、过滤与编辑中的行为。

概览(Overview)

时间单元格类型让你将单元格值视作时间:格式化其显示方式,并校验输入。使用intl-timetime单元格类型,配合原生Intl.DateTimeFormatAPI 与 24 小时制时间字符串。

从源码结构看,这两种类型在handsontable/src/cellTypes/目录中各自独立实现:

  • handsontable/src/cellTypes/intlTimeType/intlTimeType.ts定义CELL_TYPE = 'intl-time',组合了IntlTimeEditorintlTimeRendererintlTimeValidatorsourceDataValidatorvalueFormatter
  • handsontable/src/cellTypes/timeType/timeType.ts定义CELL_TYPE: 'time' = 'time',组合了TimeEditortimeRenderertimeValidator等。

两者均挂载在handsontable/src/cellTypes/registry.ts的单元格类型注册表中,可通过type: 'intl-time'type: 'time'直接使用。

时间单元格类型演示

在官方演示(见docs/content/guides/cell-types/time-cell-type/javascript/example1.js)中,StartBreak startEnd三列使用时间单元格类型并配以不同格式:短样式(timeStyle: 'short')、自定义"时:分:秒"格式(hour/minute/second),以及带日周期(dayPeriod)的格式。演示还提供了 locale 选择器,切换后会调用hot.updateSettings({ locale: ... })实时重渲染,观察同一timeFormat在不同 locale 下的显示差异。

示例数据采用 24 小时制字符串,例如:

const data = [ { shift: 'Morning', start: '09:00', breakStart: '12:00', end: '17:00' }, { shift: 'Afternoon', start: '13:30', breakStart: '16:00', end: '21:00' }, { shift: 'Night', start: '22:00', breakStart: '01:00', end: '06:00' }, { shift: 'Split', start: '08:00', breakStart: '12:30', end: '20:00' }, { shift: 'Short day', start: '10:00', breakStart: '13:00', end: '15:00' }, ];

对应的列配置为:

columns: [ { type: 'text', data: 'shift' }, { type: 'intl-time', data: 'start', timeFormat: { timeStyle: 'short' } }, { type: 'intl-time', data: 'breakStart', timeFormat: { hour: '2-digit', minute: '2-digit', second: '2-digit' } }, { type: 'intl-time', data: 'end', timeFormat: { hour: 'numeric', hourCycle: 'h12', dayPeriod: 'short' } }, ], columnSorting: true, filters: true, dropdownMenu: true,

该演示同时启用了columnSortingfiltersdropdownMenu,直接验证了时间列上的排序与过滤能力。演示完整 HTML 骨架见 example1.html,React、Angular、Vue 版本分别位于 example1.jsx、example1.tsx、example1.ts、example1.html 与 example1.vue。

使用时间单元格类型

使用对象式(object-style)配置:将type选项设为'intl-time''time',并把timeFormat设为对象。locale 通过locale选项单独控制。

为整个表格设置

// set the time cell type for the entire grid type: 'intl-time', locale: 'en-US', timeFormat: { hour: 'numeric', minute: '2-digit', second: '2-digit', hour12: true },

为单个列设置

columns: [ { type: 'intl-time', locale: 'en-US', timeFormat: { timeStyle: 'medium' } } ],

为单个单元格设置

cell: [ { row: 0, col: 2, type: 'intl-time', locale: 'en-US', timeFormat: { hour: '2-digit', minute: '2-digit', hour12: true } } ],

说明:timeFormat的默认值见handsontable/src/renderers/timeRenderer/timeRenderer.ts中的DEFAULT_INTL_FORMAT{ hour: 'numeric', minute: '2-digit' })。即不显式配置时,默认显示"时:分"。

对于intl-timetime单元格,源数据必须是 24 小时制时间格式HH:mmHH:mm:ssHH:mm:ss.SSS),时间才能正常工作。timeFormat对象只影响显示;排序与过滤依赖底层值。

格式化时间

要控制时间在单元格渲染器中的显示方式,使用timeFormat选项。

自 Handsontable 18.0 起,timeFormat对象形式intl-timetime单元格类型为必选项。它使用原生Intl.DateTimeFormatAPI;locale 通过locale选项单独控制。

使用 Intl.DateTimeFormat

timeFormat接受Intl.DateTimeFormatoptions 中与时间相关的属性,搭配type: 'intl-time'type: 'time'使用:

columns: [ { type: 'intl-time', locale: 'en-US', timeFormat: { hour: 'numeric', minute: '2-digit', second: '2-digit', hour12: true } }, { type: 'intl-time', locale: 'de-DE', timeFormat: { timeStyle: 'medium' } } ]

注意:从源码看,若把timeFormat传成字符串,valueFormatter会在控制台输出警告"The timeFormat option as a string is not supported. Use an Intl.DateTimeFormatOptions object instead.",并回退到默认格式——因此请始终使用对象形式。

时间专属选项

样式快捷方式:

属性可选值说明
timeStyle'full''long''medium''short'时间格式样式(时、分、秒、timeZoneName)

时间分量选项:

属性可选值说明
hour'numeric''2-digit'小时表示
minute'numeric''2-digit'分钟表示
second'numeric''2-digit'秒表示
fractionalSecondDigits123秒的小数位
dayPeriod'narrow''short''long'日周期(如 "am")
timeZoneName'long''short''shortOffset''longOffset''shortGeneric''longGeneric'时区显示

Locale 与其他选项:

属性可选值说明
localeMatcher'best fit'(默认)、'lookup'Locale 匹配算法
timeZoneIANA 时区(如'UTC''America/New_York'格式化使用的时区
hour12truefalse12 小时制 vs 24 小时制
hourCycle'h11''h12''h23''h24'小时周期
formatMatcher'basic''best fit'(默认)格式匹配算法

完整参考见timeFormatAPI 文档 或 MDN: Intl.DateTimeFormat。

编辑器行为

timeFormat控制时间在单元格中的显示。编辑器可能会以规范化形式显示值;对于intl-timetime,底层值始终保持 24 小时制(HH:mmHH:mm:ssHH:mm:ss.SSS)。

从源码看,TimeEditor继承自TextEditor,但把输入元素创建为原生type="time"的 input,并强制dir="ltr";打开编辑器时会调用原生showPicker()弹出系统时间选择器;若传入的值不满足 24 小时制格式,会输出警告并清空输入。IntlTimeEditor(见handsontable/src/editors/intlTimeEditor/intlTimeEditor.ts)则直接继承TimeEditor,仅替换类型标识。

结果(Result)

配置完成后,单元格按你的timeFormat配置显示格式化后的时间值。点击intl-timetime单元格会打开原生时间选择器。无论显示格式如何,源数据始终以 24 小时制(HH:mmHH:mm:ssHH:mm:ss.SSS)存储。

键盘快捷键

intl-timetime单元格编辑器打开浏览器原生时间选择器。选择器内部的键盘导航来自浏览器,因此在不同浏览器与操作系统间有所差异。选择器之外,标准编辑键盘快捷键适用。

深入原理:底层的数据格式与校验

理解源码能帮你避免"显示正常但数据异常"的坑:

时间正则与解析

handsontable/src/helpers/dateTime.ts中定义了 24 小时制时间正则:

export const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d)(?:\.(\d{1,3}))?)?$/;
  • isValidTime(value):判断字符串是否匹配上述HH:mmHH:mm:ssHH:mm:ss.SSS模式;
  • parseToLocalTime(value):把 24 小时制时间字符串解析为本地时区Date(基准日期为1970-01-01),再交给Intl.DateTimeFormat做显示格式化。这也解释了为什么timeFormat中的timeZone选项会影响显示:格式化发生在解析出的本地Date之上。

校验器与源数据校验

handsontable/src/validators/timeValidator/timeValidator.ts中:

  • timeValidator:单元格编辑时的校验器,allowEmpty时允许空值,否则用isValidTime校验;
  • sourceDataValidator:批量加载/写入源数据时逐格校验,同样基于isValidTime;当单元格元数据allowEmpty为空值时放行;以=开头的字符串视为公式表达式(由 Formulas 插件处理)而跳过校验;并标记rowIndependent = true以允许源数据校验复用列级 meta 对象,提升性能;
  • SOURCE_DATA_WARNING_MESSAGE:源数据中出现不合法时间值时输出的警告文案,明确指出期望HH:mmHH:mm:ssHH:mm:ss.SSS格式。

intlTimeValidator直接委托timeValidator,仅替换类型标识。因此两种单元格类型在编辑校验与源数据校验上行为一致。

排序与过滤依赖底层值

由于排序与过滤基于单元格底层值(24 小时制字符串)而非渲染后的显示文本,相同时间在不同 locale/格式下仍能正确排序、过滤——这正是指南开头强调"源数据必须 24 小时制"的原因。演示中columnSorting: truefilters: true即为该能力的直接验证。

相关文章

相关指南

  • 单元格类型(Cell type)

配置选项

  • timeFormat
  • locale
  • type
  • valueFormatter
  • valueParser
  • valueSetter
  • valueGetter

核心方法

  • getCellMeta()
  • getCellMetaAtRow()
  • getCellsMeta()
  • getDataType()
  • setCellMeta()
  • setCellMetaObject()
  • removeCellMeta()

钩子(Hooks)

  • afterGetCellMeta
  • afterSetCellMeta
  • beforeGetCellMeta
  • beforeSetCellMeta

【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look & Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/21 17:09:48

Java与ABAP标记接口设计模式对比与实践

1. 项目概述:当代码需要"暗号"时在面向对象编程的世界里,我们常常会遇到这样的场景:某些类需要被特殊对待,但又不想通过继承体系或显式接口来暴露这种特殊性。就像特种部队成员需要隐藏身份但内部又能快速识别一样&…

作者头像 李华
网站建设 2026/9/21 16:59:41

DLSS Swapper 教程:免费切换 DLSS/FSR/XeSS 版本,不用等游戏更新

DLSS Swapper 教程:免费切换 DLSS/FSR/XeSS 版本,不用等游戏更新 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper 是一款免费的 DLSS 版本切换工具:它让你直接下载、管理…

作者头像 李华
网站建设 2026/9/21 16:45:47

可再生能源与电动汽车协同调度的两阶段随机规划实现

1. 项目背景与研究价值在能源结构转型的大背景下,这个硕士论文复现项目聚焦于解决两个关键问题:如何高效消纳波动性强的可再生能源发电,以及如何利用规模化电动汽车(EV)的灵活性实现电网协同优化。我之所以选择复现这个…

作者头像 李华
网站建设 2026/9/21 16:43:58

PyCharm安装pyserial全攻略:从pip报错到串口联调实战

前阵子做一个小工具,要用HC05蓝牙模块和电脑串口通信,结果在PyCharm里第一步就栽在了装pyserial上。这个库看着简单,网上一搜教程满天飞,可真照着操作下来,各种报错照样能把人绕晕:“pip不是内部或外部命令…

作者头像 李华
网站建设 2026/9/21 16:41:59

TiXL InvertFloat 操作符详解:浮点数值取反的节点实现与实战用法

TiXL InvertFloat 操作符详解:浮点数值取反的节点实现与实战用法 【免费下载链接】t3 TiXL is an open source software to create realtime motion graphics. 项目地址: https://gitcode.com/GitHub_Trending/t3/t3 InvertFloat 是 TiXL 操作符库中一个轻量…

作者头像 李华