ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

NG-ZORRO DatePicker 的 nzFormat 深度解析:从默认格式推导到 date-fns 令牌实现

NG-ZORRO DatePicker 的 nzFormat 深度解析:从默认格式推导到 date-fns 令牌实现 UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载本文围绕 NG-ZORRO 日期选择器的 nzFormat 官方示例 展开讲解nzFormat如何控制nz-date-picker与nz-range-picker的输入框显示格式它如何按选择模式自动推导默认值、如何在运行时动态切换并即时重渲染输入框、格式串又是如何交给底层日期适配器date-fns / native解释的。读完后你将能够自定义任意展示格式、理解季度格式yyyy/[Q]Q中方括号的字面量语义并在切换日期库时正确适配格式令牌。nzFormat 是什么自定义日期显示格式官方示例文档的核心结论只有一句话使用nzFormat属性可以自定义日期显示格式。对应的可运行示例位于 components/date-picker/demo/format.ts它覆盖了四种典型用法——普通日期、月份模式、季度模式以及范围选择器Component({ selector: nz-demo-date-picker-format, imports: [NzDatePickerModule], template: nz-date-picker [nzFormat]dateFormat / br / nz-date-picker nzModemonth [nzFormat]monthFormat / br / nz-date-picker nzModequarter [nzFormat]quarterFormat / br / nz-range-picker [nzFormat]dateFormat / , styles: nz-date-picker, nz-range-picker { margin: 0 8px 12px 0; } }) export class NzDemoDatePickerFormatComponent { dateFormat yyyy/MM/dd; monthFormat yyyy/MM; quarterFormat yyyy/[Q]Q; }四个选择器演示了nzFormat的三类关键特性日期模式nzModedate默认yyyy/MM/dd将输入框展示为2024/03/04风格月份模式nzModemonthyyyy/MM只保留到月季度模式nzModequarteryyyy/[Q]Q展示为2024/Q1——注意方括号内的Q是字面量而非季度令牌范围选择器nz-range-picker共享同一个nzFormat左右两个输入框按同一格式渲染。nzFormat在组件中的声明见 date-picker.component.tsInput() nzFormat!: string;它是一个普通的字符串输入没有类型约束——这正意味着格式串的最终解释权在日期适配器手中这一点下文会展开。默认格式推导不传 nzFormat 时会发生什么在 date-picker.component.ts 的setModeAndFormat()中组件初始化及nzMode变化时会按模式推导默认格式setModeAndFormat(): void { const inputFormats: PartialRecordNzDateMode, string { year: yyyy, quarter: yyyy-[Q]Q, month: yyyy-MM, week: YYYY-ww, date: this.nzShowTime ? yyyy-MM-dd HH:mm:ss : yyyy-MM-dd }; if (!this.nzMode) { this.nzMode date; } this.panelMode this.isRange ? [this.nzMode, this.nzMode] : this.nzMode; // Default format when its empty if (!this.isCustomFormat) { this.nzFormat inputFormats[this.nzMode as NzDateMode]!; } this.inputSize Math.max(10, this.nzFormat.length) 2; this.updateInputValue(); }由此得到完整的默认格式对照表选择模式nzMode默认nzFormat展示效果示例yearyyyy2024quarteryyyy-[Q]Q2024-Q1monthyyyy-MM2024-03weekYYYY-ww2024-09ISO 周年-周数date不含时间yyyy-MM-dd2024-03-04datenzShowTimeyyyy-MM-dd HH:mm:ss2024-03-04 12:30:05从源码结构看这里还有两个值得注意的细节isCustomFormat标志只要用户显式赋过nzFormatngOnChanges中就会置位该标志见 date-picker.component.ts此后切换nzMode也不会再覆盖用户的自定义格式。输入框宽度随格式长度自适应inputSize Math.max(10, this.nzFormat.length) 2。格式串越长input 的size属性越大避免格式化后的文本被截断。nzShowTime对象形式还支持独立的时间区格式官方 API 文档components/date-picker/doc/index.zh-CN.md列出了nzShowTime支持的参数nzFormat、nzHourStep、nzMinuteStep、nzSecondStep、nzDisabledHours、nzDisabledMinutes、nzDisabledSeconds、nzHideDisabledOptions、nzDefaultOpenValue、nzAddOn。仓库内 time 示例 展示了nzFormatyyyy-MM-dd HH:mm搭配[nzShowTime]{ nzFormat: HH:mm }的写法——即输入框整体格式与面板时间列格式可以分开控制。格式化与输入校验nzFormat 的双向作用nzFormat不只是“展示用”的它同时定义了输入解析规则。组件内的两条关键路径1. 值 → 展示formatdate-picker.component.tsformatValue(value: CandyDate | null): string { return value ? this.dateAdapter.format(value.nativeDate, this.nzFormat) : ; }范围选择器则对左右两个值分别执行同样格式化date-picker.component.tsupdateInputValue(): void { const newValue this.datePickerService.value; if (this.isRange) { this.inputValue newValue ? (newValue as CandyDate[]).map(v this.formatValue(v)) : [, ]; } else { this.inputValue this.formatValue(newValue as CandyDate); } this.cdr.markForCheck(); }2. 展示 → 值parse用户在输入框手动输入文本时date-picker.component.ts 用同一格式串做解析并做往返一致性校验private checkValidDate(value: string): CandyDate | null { const date new CandyDate(this.dateAdapter.parse(value, this.nzFormat)); if (!date.isValid() || value ! this.dateAdapter.format(date.nativeDate, this.nzFormat)) { return null; } return date; }这段逻辑意味着输入文本必须先能按nzFormat解析出合法日期且再格式化回去必须与原输入逐字符一致否则视为非法输入面板不会跟随输入变化。例如格式为dd.MM.yyyy时输入4.3.2020会被拒绝必须写成04.03.2020——这也解释了为什么日期格式中的MM、dd建议使用双字母令牌来强制补零。测试用例 date-picker.component.spec.ts 验证了上述行为it(should support nzFormat, async () { fixtureInstance.nzFormat.set(dd.MM.yyyy); fixtureInstance.nzValue.set(new Date(2020-03-04)); // ... expect(input.value).toBe(04.03.2020); });运行时动态切换格式即时重渲染且不触发变更ngOnChanges中对nzFormat的处理date-picker.component.tsif (nzFormat?.currentValue) { this.isCustomFormat true; this.updateInputValue(); }格式变化后组件立刻用新格式重渲染输入框文本。测试 should rerender input value when nzFormat changed 证实了这条链路的两个要点值2025-05-23在dd.MM.yyyy下显示23.05.2025切换为dd/MM/yyyy后立即变为23/05/2025纯格式切换不会触发nzOnChangeexpect(nzOnChange).not.toHaveBeenCalled()——因为底层的Date值没有变化表单值保持稳定。这对做“多格式切换预览”或国际化展示的场景非常关键改格式只是改视图不会污染表单状态。另外nzFormat还会通过[format]nzFormat传入面板组件date-picker.component.ts影响内联面板的周数展示等依赖格式的渲染细节。格式令牌的最终解释者日期适配器nzFormat是string类型组件本身不解析令牌格式化与解析全部委托给注入的NzDateAdapter见 date-picker.component.ts 中的inject(NzDateAdapter)。从 v22 开始NG-ZORRO不再默认提供日期引擎适配器需要在应用根配置中显式提供官方说明见 docs/date-adapter.zh-CN.md// 使用内置 date-fns 适配器 import { ApplicationConfig } from angular/core; import { zhCN } from date-fns/locale; import { provideNzDateFnsAdapter } from ng-zorro-antd/core/time; export const appConfig: ApplicationConfig { providers: [provideNzDateFnsAdapter({ locale: zhCN, firstDayOfWeek: 1 })] }; // 或使用原生 Date Intl.DateTimeFormat 语义 // import { provideNzNativeDateAdapter } from ng-zorro-antd/core/time; // providers: [provideNzNativeDateAdapter({ locale: zh-CN, firstDayOfWeek: 1 })]date-fns 适配器Angular 方括号字面量到 date-fns 单引号的转换内置 DateFnsDateAdapter 的format/parse实现date-fns-adapter.tsformat(date: Date, displayFormat: NzSafeAny): string { if (!date) { return ; } if (!this.isValid(date)) { throw new Error(DateFnsDateAdapter: Cannot format invalid date.); } // Convert Angular-style bracket literals to date-fns single-quote literals // e.g., yyyy-[Q]Q → yyyy-QQ const formatString (displayFormat as string).replace(/\[(.*?)\]/g, $1); return fnsFormat(date, formatString, { locale: this.locale, useAdditionalWeekYearTokens: true, useAdditionalDayOfYearTokens: true }); }这里揭示了示例中yyyy/[Q]Q能工作的原理NG-ZORRO 采用 Angular 风格的方括号字面量[...]内的内容按字面输出而 date-fns 原生用单引号表示字面量适配器在调用fnsFormat前把[Q]统一改写为Q于是yyyy/[Q]Q实际执行的是yyyy-QQ输出2024/Q1。parse做了同样的转换并支持传入格式数组逐个尝试解析。因此在使用 date-fns 适配器时nzFormat的令牌语法即 date-fns 格式令牌语法yyyy四位年、MM月、dd日、HH/mm/ss时分秒、Q/QQQQ季度、wwISO 周数等并附加启用了useAdditionalWeekYearTokens与useAdditionalDayOfYearTokens使YYYY、gggg、DDD等扩展令牌可用——这正是默认格式week: YYYY-ww能成立的原因。native 适配器令牌串或 Intl 选项内置的 native 适配器native-adapter.ts对format采取双轨解释传入Intl.DateTimeFormatOptions对象时直接委托Intl.DateTimeFormat传入字符串时走自己的formatByToken令牌替换内部用Intl.DateTimeFormat生成MMMM、MMMM月份名、星期名等片段。也就是说同一份nzFormat字符串在不同适配器下的可用令牌集合可能不同。官方文档对此有明确提醒切换日期库后请确认nzFormat、默认格式和手动解析格式都符合新日期库的令牌语法docs/date-adapter.zh-CN.md。历史兼容提示旧版DateHelperService/DateHelperByDateFnsdate-helper.service.ts已被标记deprecatedv23 移除其replaceQuarter逻辑负责了早期版本中Q令牌的兼容处理新项目应直接使用NzDateAdapter。实战建议与注意事项与模式匹配nzModemonth时不要写dd令牌——月份面板没有“日”格式里含日令牌只会让输入解析与面板行为错位。示例中monthFormat yyyy/MM是最简写法。季度格式记住方括号yyyy/[Q]Q或默认的yyyy-[Q]Q中[Q]是字面量 QQ才是季度号若把两者弄反date-fns 会把yyyy-QQ解析为季度令牌而抛错或得到非预期结果。输入校验要求严格匹配由于checkValidDate的往返一致性检查展示格式与用户输入必须完全同构若希望用户输入更宽松例如允许4/3/2020可考虑自定义适配器的parse支持格式数组。动态改格式是纯视图行为切换nzFormat会即时重渲染输入框但不会触发(nzOnOk)、ngModelChange等值变更回调表单数据保持不变。v22 前提日期类组件依赖应用根部提供的NzDateAdapter。未配置时相关组件无法工作nzFormat令牌语义也以你所选适配器为准NZ_I18N控制组件文案adapter 的locale控制月份名、星期名、周起始日等格式细节运行时切换语言时需同步调用dateAdapter.setLocale(...)。范围选择器两端共用一个格式nz-range-picker的nzFormat同时作用于起止两个输入框且组件按nzFormat.length统一计算输入宽度。延伸阅读官方格式示例components/date-picker/demo/format.md、components/date-picker/demo/format.ts核心实现components/date-picker/date-picker.component.tssetModeAndFormat、formatValue、checkValidDate、ngOnChanges日期适配器components/core/time/date-fns-adapter.ts、components/core/time/native-adapter.ts、docs/date-adapter.zh-CN.mdAPI 总览与nzShowTime参数说明components/date-picker/doc/index.zh-CN.md行为测试components/date-picker/date-picker.component.spec.ts赞分享UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载相关推荐掌握date-fns时间格式化Unicode令牌完全指南掌握date fns时间格式化Unicode令牌完全指南 date fns是一个现代JavaScript日期工具库提供了简洁、模块化的时间处理功能。本文将深前端后端date-fns日期格式化与解析深度指南date fns日期格式化与解析深度指南 本文深入探讨了date fns库中日期格式化与解析的核心功能包括format函数的格式化机制、parseISO和pa前端后端date-fns Haitian Creolehtlocale 快照全解析format/parse 令牌、距离格式化与源码实现date fns Haitian Creolehtlocale 快照全解析format/parse 令牌、距离格式化与源码实现 本篇技术指南基于 date前端后端上一篇ModernVBERT轻量化视觉语言模型的突破性进展下一篇Kani TTS 370M重新定义实时对话式AI的语音交互体验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表