Home Assistant 前端时间格式化(含秒)指南:formatTimeWithSeconds 的实现与多语言演示
前端智能家居UI组件【免费下载链接】frontend:lollipop: Frontend for Home Assistant项目地址https://gitcode.com/gh_mirrors/frontend149/frontend点击查看免费下载本篇指南围绕 Home Assistant 前端frontend仓库中 Gallery 组件的 time-seconds 演示页面展开深入剖析formatTimeWithSeconds这一时间格式化函数的定义、底层实现、参数行为与真实应用场景。读者读完本文将掌握 Home Assistant 前端如何基于Intl.DateTimeFormat实现多语言、12/24 小时制可切换的时分秒时间格式化并能独立在 Lovelace 自定义卡片或前端组件中复用这一能力。一、Gallery 中的Time Format (Seconds)页面是什么在 frontend 仓库中Gallery组件演示平台位于 gallery 目录其用途是集中展示前端各类组件与本地化i18n效果。gallery/src/pages/date-time/目录下集中了日期时间相关的全部演示页面包括time.markdown不带秒的时间格式演示time-seconds.markdown带秒的时间格式演示本文主题time-weekday.markdown带星期的演示date.markdown、date-time.markdown 等日期与日期时间格式演示关联文档 time-seconds.markdown 的核心内容非常聚焦页面标题为Time Format (Seconds)用于列出所有受支持语言及其可用的含秒时间格式该页面演示所使用的格式化函数为const formatTimeWithSeconds: (dateObj: Date, locale: FrontendLocaleData) string也就是说这是一个多语言、多格式对照表性质的演示页同一时刻在同一语言下分别以语言默认格式、12 小时制、24 小时制三种方式输出时:分:秒方便开发者直观对比各语言的表现差异。二、演示组件的实现三列对比所有语言与 markdown 文档一一对应的演示组件是 gallery/src/pages/date-time/time-seconds.ts这是一个基于 LitElement 的自定义元素demo-date-time-time-seconds。其核心逻辑可以拆解为四部分。2.1 可切换的演示时间组件顶部使用ha-control-select下拉选择器选项来自 gallery/src/data/date-options.tsexport const timeOptions: ControlSelectOption[] [ { value: now, label: Now }, { value: 00:15:30, label: 12:15:30 AM }, { value: 06:15:30, label: 06:15:30 AM }, { value: 12:15:30, label: 12:15:30 PM }, { value: 18:15:30, label: 06:15:30 PM }, ];默认选中now当前时刻当选择某个固定时刻时组件将HH:MM:SS字符串拆分后写入Date对象的setHours/setMinutes/setSeconds从而在多个语言列之间使用同一个时间点进行对照保证结果可比if (this.selection ! now) { const [hours, minutes, seconds] this.selection.split(:).map(Number); this.date.setHours(hours); this.date.setMinutes(minutes); this.date.setSeconds(seconds); }2.2 基准 Locale 与三种输出列组件构造了一个英文基准FrontendLocaleData结构定义见 src/data/translation.ts随后遍历translationMetadata.translations中所有受支持语言为每种语言渲染一行三列Default (lang)time_format: TimeFormat.language完全跟随语言的区域习惯12 Hourstime_format: TimeFormat.am_pm强制 12 小时制24 Hourstime_format: TimeFormat.twenty_four强制 24 小时制。其中translationMetadata来自 src/resources/translations-metadata.ts该模块读取构建产物build/translations/translationMetadata.json提供语言代码、原生语言名nativeName等元数据这正是列出所有受支持语言的数据来源。2.3 传入服务器配置注意演示代码在调用时还传入了第三个参数demoConfig来自 src/fake_data/demo_config.ts。这一点与文档中写出的函数签名只有两个参数略有差异说明实际实现中该函数还需要HassConfig来获取服务器时区详见下文实现分析。三、源码实现formatTimeWithSeconds 的底层原理核心实现位于 src/common/datetime/format_time.ts// 9:15:24 PM || 21:15:24 export const formatTimeWithSeconds ( dateObj: Date, locale: FrontendLocaleData, config: HassConfig ) formatTimeWithSecondsMem(locale, config.time_zone).format(dateObj); const formatTimeWithSecondsMem memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) new Intl.DateTimeFormat(locale.language, { hour: useAmPm(locale) ? numeric : 2-digit, minute: 2-digit, second: 2-digit, hourCycle: useAmPm(locale) ? h12 : h23, timeZone: resolveTimeZone(locale.time_zone, serverTimeZone), }) );该实现有几个值得注意的技术点。3.1 基于 Intl.DateTimeFormat与手写补零的字符串拼接不同Home Assistant 前端直接使用 ECMAScript 国际化 APIIntl.DateTimeFormat并把second: 2-digit作为关键配置项从而让每种语言都能按自己的区域规则输出秒位例如数字位数、分隔符、12/24 小时循环等均由 CLDR 区域数据驱动。这也是所有受支持语言各有其可用格式这一能力的根基。3.2 hourCycle 与 useAmPm 联动hourCycle由useAmPm(locale)决定。该工具函数位于 src/common/datetime/use_am_pm.ts当time_format为TimeFormat.am_pm12时直接返回true使用h12当time_format为TimeFormat.twenty_four24时返回false使用h23当time_format为TimeFormat.language跟随语言或TimeFormat.system时则以一个固定的测试时间new Date(January 1, 2023 22:00:00)调用toLocaleString通过结果中是否包含10来推断该语言默认采用 12 还是 24 小时制——这是一个巧妙且无需额外语言数据的启发式判定。3.3 时区解析本地 vs 服务器timeZone由 src/common/datetime/resolve-time-zone.ts 中的resolveTimeZone决定若用户设置time_zone为TimeZone.local且浏览器能解析出合法的 IANA 时区名如Asia/Shanghai则使用浏览器本地时区否则回退到HassConfig.time_zone服务器时区代码还对 Android 模拟器等返回00:00偏移量而非 IANA 名称的环境做了防御处理避免把非法时区传给Intl。3.4 memoizeOne 性能优化formatTimeWithSecondsMem使用memoizeOne按(locale, serverTimeZone)缓存Intl.DateTimeFormat实例。由于 Gallery 演示会对每一种语言调用一次该函数缓存机制避免了反复构造格式化器对象这在多语言对照渲染场景下是明显的性能保障。四、12 小时制与 24 小时制TimeFormat 枚举与测试验证用户可选的time_format取值定义在 src/data/translation.tsexport enum TimeFormat { language language, system system, am_pm 12, twenty_four 24, }其中am_pm12与twenty_four24正是 Gallery 演示页中12 Hours / 24 Hours两列所对应的强制模式而language对应Default (lang)列。仓库的单元测试 test/common/datetime/format_time.test.ts 对formatTimeWithSeconds给出了精确断言可作为理解其行为的最佳佐证const dateObj new Date(2017, 10, 18, 23, 12, 13, 400); // time_format: am_pm → 期望输出 11:12:13 PM // time_format: twenty_four → 期望输出 23:12:13同一时刻23:12:13在 12 小时制下显示为11:12:13 PM在 24 小时制下显示为23:12:13与函数头注释// 9:15:24 PM || 21:15:24完全一致。五、函数族一个完整的时间格式化体系formatTimeWithSeconds并非孤立存在它与 format_time.ts 中的其他函数共同构成时间格式化体系可根据精度与语义选择函数输出示例说明formatTime9:15 PM \|\| 21:15精确到分钟formatTimeWithSeconds9:15:24 PM \|\| 21:15:24精确到秒本文主题formatTimeWithMilliseconds9:15:24.123 PM \|\| 21:15:24,123精确到毫秒小数分隔符随区域变化法语为逗号formatTimeWeekdaySaturday 11:12 PM分钟精度并附带星期formatTime24h21:15强制 24 小时制源码注释特别提到使用en-GB区域以规避 Chrome 中24:59显示为0:59的已知问题毫秒函数的小数分隔符行为也有测试覆盖法语区域下23:12:13.400会输出为23:12:13,400见 format_time.test.ts印证了格式完全由区域数据驱动的设计。六、真实应用场景hui-timestamp-display 中的 long 时间格式formatTimeWithSeconds在前端产品代码中的典型使用位置是 Lovelace 的 hui-timestamp-display.ts。该组件维护了一张格式表const FORMATS { date: { default: formatDate, short: formatDateNumeric }, datetime:{ default: formatDateTime, short: formatDateTimeNumeric }, time: { default: formatTime, long: formatTimeWithSeconds }, };当配置项format为{ type: time, style: long }时时间戳将以含秒的格式渲染同时无论采用相对时间还是静态格式当tooltip开启时悬浮提示统一使用formatDateTimeWithSeconds日期时间 秒展示完整精确时刻。这说明formatTimeWithSeconds承担着高精度时间呈现的角色适合日志时间戳、事件时刻、设备状态上报等需要秒级分辨率的场景。七、如何运行与扩展验证若想在本地复现 Gallery 页面效果可运行 gallery 的开发脚本pnpm run gallery:develop具体命令见 gallery/script/develop_gallery。构建则使用 gallery/script/build_gallery。在自定义卡片或前端组件中复用该能力的标准调用方式如下import { formatTimeWithSeconds } from ../../src/common/datetime/format_time; const now new Date(); const locale: FrontendLocaleData { language: zh-Hans, number_format: NumberFormat.language, time_format: TimeFormat.language, // 或 12 / 24 date_format: DateFormat.language, first_weekday: FirstWeekday.language, time_zone: TimeZone.local, }; const text formatTimeWithSeconds(now, locale, hass.config);小结以 time-seconds.markdown 为入口可以看到Home Assistant 前端把带秒的时间格式化做成了一个以Intl.DateTimeFormat为核心、由useAmPm与resolveTimeZone两个工具函数协同决策、以memoizeOne缓存保障性能的完整能力并通过 Gallery 演示页对全部受支持语言进行 12/24 小时制的对照展示。理解formatTimeWithSeconds也就理解了这套前端时间本地化体系的基本运作方式可直接将其移植到自定义卡片与 Lovelace 组件中。赞分享前端智能家居UI组件【免费下载链接】frontend:lollipop: Frontend for Home Assistant项目地址https://gitcode.com/gh_mirrors/frontend149/frontend点击查看免费下载相关推荐Home Assistant 前端日期时间格式指南formatDateTime 函数与多语言格式画廊全解析Home Assistant 前端日期时间格式指南formatDateTime 函数与多语言格式画廊全解析 本篇技术指南以 Home Assistantho前端智能家居UI组件Home Assistant Frontend 日期时间短格式解析formatShortDateTime 的多语言格式化实现与 Gallery 实践Home Assistant Frontend 日期时间短格式解析formatShortDateTime 的多语言格式化实现与 Gallery 实践 导读 本前端智能家居UI组件Home Assistant 前端数值日期格式化完整指南读懂 formatDateNumeric 与多语言日期顺序Home Assistant 前端数值日期格式化完整指南读懂 formatDateNumeric 与多语言日期顺序 本指南围绕 Home Assistant前端智能家居UI组件上一篇告别复杂JSON处理GRDB.swift终极Codable与JSON列实战指南下一篇Catberry渐进式渲染揭秘为什么你的应用加载更快创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考