☰
Decap CMS 的 datetime 日期时间组件:配置详解、源码实现与版本演进
2026/10/1 9:44:58 网站建设 项目流程

【免费下载链接】decap-cms

A Git-based CMS for Static Site Generators

项目地址:https://gitcode.com/gh_mirrors/de/decap-cms
点击查看免费下载

本文以packages/decap-cms-widget-datetime的 CHANGELOG.md 为脉络,结合该组件 DateTimeControl.js、schema.js 等源码与单元测试,系统讲解 Decap CMS 中 datetime 组件的配置方式、底层行为、时区处理与关键版本变更。读完本文,你将掌握该组件的全部字段参数、{{now}}默认值机制、UTC/本地时间差异,以及从 moment 迁移到 dayjs 背后的设计取舍。

datetime 组件在 Decap CMS 中的定位

Decap CMS 是一个基于 Git 的静态站点 CMS,其编辑界面由一系列"组件(Widget)"构成,每个组件对应一种字段类型。datetime组件专门负责日期、时间以及日期时间的输入与展示,用于发布日、更新时间、事件时间等场景。

从 package.json 可以看到,该包是独立发布、可单独安装的 npm 包,通过 index.js 对外注册:

function Widget(opts = {}) { return { name: 'datetime', controlComponent, previewComponent, schema, ...opts, }; }

其中controlComponent(编辑控件)、previewComponent(预览组件)与schema(配置项校验规则)共同组成了组件的完整能力。在 dev-test/config.yml 中可以看到它的真实使用示例:

- { label: 'Publish Date', name: 'date', widget: 'datetime', format: 'YYYY-MM-DD HH:mm', default: '{{now}}', }

配置参数详解:四个核心字段

组件的可配置参数由 schema.js 声明并校验:

参数类型说明
formatstring最终写入内容文件(YAML/Markdown 等)的日期格式,优先级最高
date_formatstring 或 boolean日期部分格式;true时使用默认YYYY-MM-DD,false时隐藏日期部分
time_formatstring 或 boolean时间部分格式;true时使用默认HH:mm,false时隐藏时间部分
picker_utcboolean是否以 UTC 时区解析与展示日期时间,默认false

format:最终存储格式

format决定字段值以何种字符串形式写入内容文件。在 DateTimeControl.js 中,一旦配置了format,它就会覆盖由date_format/time_format拼装出的默认格式,并将输入控件类型固定为datetime-local。

未配置format时的默认格式(源码 getFormat()):

  • 本地时区:YYYY-MM-DDTHH:mm:ss.SSSZ(如2026-09-30T10:30:00.000+08:00)
  • UTC 时区(picker_utc: true):YYYY-MM-DDTHH:mm:ss.SSS[Z],Z被转义为字面量

这一行为经历过两次调整:3.1.0-beta.3 变更了 datetime 组件的值格式,3.1.3 又回退为包含时区的默认格式(见 CHANGELOG 中 "revert default date format to include timezone"),最终形成了上面带时区后缀的稳定默认值。

date_format 与 time_format:拆分控制

这两个参数允许只显示日期或只显示时间:

  • 只配置date_format: 'YYYY-MM-DD':输入控件降级为原生date类型,存储格式即该日期格式;
  • 只配置time_format: 'HH:mm':输入控件降级为原生time类型;
  • date_format: false强制隐藏日期、time_format: false强制隐藏时间(DateTimeControl.js#L116-L117);
  • 两者同时配置且均为字符串时,按${dateFormat}T${timeFormat}拼接为完整格式(DateTimeControl.js#L101-L102)。

对应的输入控件原生类型也随配置切换:datetime-local、date、time,分别匹配YYYY-MM-DDTHH:mm、YYYY-MM-DD、HH:mm三种输入格式。

picker_utc:UTC 与本地时间

picker_utc于 2.5.0 引入(CHANGELOG "add pickerUtc option to datetime widget")。开启后:

  • 日期解析、当前时间获取均基于dayjs.utc()(DateTimeControl.js#L127-L130);
  • 输入框旁会显示 "UTC" 标识(DateTimeControl.js#L196-L205);
  • 用户自定义格式中的Z会被 escapeZ() 转义为[Z],避免被 dayjs 误解析为时区占位符。
# 使用 UTC 的配置示例 - { label: 'Event Time', name: 'event_time', widget: 'datetime', picker_utc: true }

default 与 {{now}}:默认值机制(重要行为变更)

这是 CHANGELOG 中最关键的行为变化:

3.2.0(2024-08-12)破坏性变更:datetime 字段默认不再预填当前日期(此前会自动预填),如需预填当前时间必须显式配置default: '{{now}}'。

在 DateTimeControl.js#L65-L73 中,组件挂载时会检测值是否为'{{now}}'字面量,若是则调用getNow()将其替换为当前时间并触发onChange:

componentDidMount() { const { value } = this.props; if (value === '{{now}}') { this.handleChange(this.getNow()); } }

3.2.3 又修复了 "trigger change if default is {{now}}"(#7272),确保{{now}}能正确触发变更通知。升级到 3.2.0 及以后版本时,若希望字段自动填充当前时间,必须显式声明default: '{{now}}',这是迁移时最需要留意的兼容点。

底层实现:值的双向转换链路

datetime 组件的核心逻辑集中在 DateTimeControl.js 中,整个数据流可以概括为三条链路:

  1. 读取回显:formatInputValue(value)把存储格式的值转换为输入框所需的格式。它优先用dayjs(value, format)按存储格式解析后重新格式化;解析失败(如format未提供、值本身不可解析)时,会回退到dayjs(value)的宽松解析(DateTimeControl.js#L132-L144)。3.1.4 修复了 "formatInputValue ignoring format" 问题,3.1.5 修复了未提供format时解析展示值的问题,这两处正是本方法的演进痕迹。

  2. 用户输入:onInputChange把输入框值交给handleChange,先通过isValidDate校验(合法的输入格式值或空串),再按存储格式格式化后写入内容(DateTimeControl.js#L146-L157):

handleChange = datetime => { if (!this.isValidDate(datetime)) return; if (datetime === '') { onChange(''); } else { const { format, inputFormat } = this.getFormat(); const formattedValue = dayjs(datetime, inputFormat).format(format); onChange(formattedValue); } };
  1. 快捷操作:Now按钮写入getNow()的当前时间,Clear按钮写入空串。这两个按钮由Buttons组件渲染(DateTimeControl.js#L14-L46),对应 2.4.0 "add now to datepicker" 与 2.7.3 "make 'now' button consistent" 两次迭代。

预览侧则非常简单:DateTimePreview仅将值原样渲染(DateTimePreview.js)。

日期解析引擎的演进:从 moment 到 dayjs

CHANGELOG 记录了组件底层依赖的两次关键升级:

  • 3.1.0-beta.1(2023-11-23):用 dayjs 替换 moment(#6980),标注为性能优化;
  • 3.1.0-beta.2(2024-01-16):将 dayjs 改为按包独立依赖(#6992)。

当前 package.json 中dependencies仅剩dayjs,并通过插件扩展能力启用三个能力(DateTimeControl.js#L4-L12):

dayjs.extend(customParseFormat); // 按指定格式解析 dayjs.extend(localizedFormat); // 本地化格式 dayjs.extend(utc); // UTC 时区支持

这解释了{{now}}、picker_utc、自定义格式解析等能力为何都能在更轻量的 dayjs 上实现——三个插件恰好覆盖了组件全部的时间处理需求。

工程化与可访问性细节

  • Schema 校验(2.6.0 引入):组件配置在保存前即通过 schema.js 校验参数类型,非法配置会提前报错。
  • 无障碍(a11y):3.4.1 为按钮补充了aria-label(#7720)。在 DateTimeControl.js#L23-L25 中,Now按钮的 aria-label 由国际化函数t('editor.editorWidgets.datetime.setToNow', { fieldLabel: fieldName })动态生成,可随语言包本地化。
  • 构建产物(2019 年前后):2.2.0 增加 ES Module 构建、2.1.0-beta.0 提供 UMD 构建、2.2.1-beta.1 修复 ESM 的 source map 导出,这些确保了组件能被decap-cms主包以多种模块方式消费。
  • 依赖清理:3.5.0 移除未使用依赖并补全缺失依赖(#7833),2.7.4/2.7.1 分别升级了历史版本使用的react-datetime至 v3,2.7.0 将 React 17 加入 peerDependencies。

单元测试如何验证组件行为

组件的测试用例位于 DateTimeControl.spec.js,覆盖了 CHANGELOG 中多项关键行为,可作为理解组件语义的"活文档":

  • Now 按钮:点击后onChange收到按配置格式(如DD.MM.YYYY)格式化的当前时间;
  • Clear 按钮:点击后onChange收到空串,对应 2.2.5 "allow empty value" 与 3.2.0 默认空值的语义;
  • 本地时区输入:输入2024-03-15T10:30:00,期望输出YYYY-MM-DDTHH:mm:ss.SSSZ格式(含本地时区偏移);
  • UTC 输入:开启picker_utc后,期望输出YYYY-MM-DDTHH:mm:ss.SSS[Z]格式(字面量Z后缀)。

测试通过jest.useFakeTimers()固定系统时间(2025-01-01T12:00:00.000Z),保证 Now 按钮相关断言稳定可复现。

升级与迁移建议

综合 CHANGELOG 与源码,升级到当前版本(3.6.0)时建议关注:

  1. 默认值变化(3.2.0 破坏性变更):若依赖旧版自动预填当前时间的行为,需为 datetime 字段补充default: '{{now}}';
  2. 默认格式含时区:3.1.0-beta.3 起默认值格式为带时区的YYYY-MM-DDTHH:mm:ss.SSSZ(UTC 模式为[Z]),如果内容文件中已有旧格式数据,建议显式配置format以保持历史兼容;
  3. dayjs 解析差异:moment 迁移到 dayjs 后,个别宽松解析场景的行为可能略有差异(3.1.4/3.1.5 的修复即与此相关),若遇到展示异常,优先检查是否配置了完整的format。

小结

decap-cms-widget-datetime是一个"小而不简单"的组件:四个配置参数控制着存储格式、日期时间拆分、时区模式三类核心行为,{{now}}默认值机制经历了破坏性变更,底层解析引擎从 moment 平稳迁移到 dayjs。通过 CHANGELOG 与 DateTimeControl.js、schema.js、DateTimeControl.spec.js 等源码和测试相互印证,你可以准确预判组件在任何配置组合下的存储值与展示行为,避免踩中时区与默认值的坑。

【免费下载链接】decap-cms

A Git-based CMS for Static Site Generators

项目地址:https://gitcode.com/gh_mirrors/de/decap-cms
点击查看免费下载
上一篇:claude-code-best-practice性能优化:内存管理与上下文优化的实用方法
下一篇:Shellharden扩展开发终极指南:如何编写自定义sit组件处理特殊语法结构

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询