尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

@wordpress/date 完全指南:在 Gutenberg 与 WordPress 中实现 PHP 风格日期格式化、国际化与时区处理

@wordpress/date 完全指南:在 Gutenberg 与 WordPress 中实现 PHP 风格日期格式化、国际化与时区处理 wordpress/date 完全指南在 Gutenberg 与 WordPress 中实现 PHP 风格日期格式化、国际化与时区处理【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenbergwordpress/date是 Gutenberg 项目中负责前端日期处理的独立 npm 包为 WordPress 编辑器及其外部使用者提供与 PHPdate()/wp_date()行为对齐的格式化、本地化与时区转换能力。本文基于 packages/date 的官方 README、核心实现 与 单元测试系统讲解全部 API 的用法、参数语义、PHP 格式符与 Moment.js 的映射原理以及站点时区WP自定义时区的底层实现帮助你在自己的项目里写出跨时区、多语言环境下正确无误的日期代码。安装与运行环境要求与所有wordpress/*系列包一样可以通过 npm 直接安装npm install wordpress/date --save该包当前版本为 5.55.0其 package.json 声明了运行环境与依赖要求Node 18.12.0、npm 8.19.2运行时依赖moment^2.29.4与moment-timezone^0.5.40以及wordpress/deprecated构建产物通过exports字段同时提供importbuild-module/index.mjs与requirebuild/index.cjs两种入口并附带build-types类型声明测试框架使用 Vitest。官方文档特别提醒该包假定你的代码运行在ES2015环境中。如果你的目标环境对语言特性与 API 支持有限或缺失需要引入 wordpress/babel-preset-default 中提供的 polyfill相关说明见该包的 README 文档。API 一览wordpress/date共导出 11 个函数与一组类型覆盖格式化、国际化、时区解析与设置管理函数作用是否本地化时区行为format按 PHP 格式符格式化日期否不改变日期的时区date格式化日期类似 PHPdate()否英文默认使用站点时区gmdate在 UTC 下格式化类似 PHPgmdate()否英文UTCdateI18n格式化并翻译为站点语言类似 PHPwp_date()是默认使用站点时区gmdateI18nUTC 下格式化并翻译为站点语言是UTCgetSettings返回当前日期设置——setSettings以wp_localize_script()提供的数据配置 moment 本地化——getDate从 WP 时区的日期字符串创建 JavaScriptDate对象——isInTheFuture判断日期是否在未来的计划时间中——humanTimeDiff返回人类可读的时间差类似 PHPhuman_time_diff()是随 localeWP 时区下文逐一深入。核心格式化函数format、date 与 gmdateformat不改变时区的纯格式化format( dateFormat, dateValue )只负责“格式化”本身不会改动日期的时区。dateValue可以是 Moment 实例、Date对象、可被 moment 解析的字符串或数字Unix 时间戳缺省时使用new Date()见 实现源码。import { format } from wordpress/date; format( Y-m-d H:i, 2019-06-18T11:00:00.000Z ); // 按传入日期的原始时区这里是 UTC输出2019-06-18 11:00其实现本质是把 PHP 风格格式串逐个字符扫描查formatMap转换成 Moment.js 的 token 后交给moment().format()执行不在映射表中的字符会被[ ]包裹作为字面量输出。date类似 PHP date()默认使用站点时区date( dateFormat, dateValue, timezone )等价于 PHP 的date()输出英文结果并默认把日期转换到站点时区。第三个参数timezone是可选的缺省时按settings.timezone中配置的站点时区或 UTC 偏移输出传入 IANA 时区名如Asia/Macau则按该时区输出传入合法的 UTC 偏移如08:00或数字8、480则按该偏移输出。import { date } from wordpress/date; // 站点时区为 America/New_York 时 date( Y-m-d H:i, 2019-06-18T11:00:00.000Z ); // 2019-06-18 07:00夏季含夏令时 // 显式指定时区 date( Y-m-d H:i, 2019-06-18T11:00:00.000Z, Asia/Macau ); // 2019-06-18 19:00 // 指定 UTC 偏移字符串、小时数或分钟数均可 date( Y-m-d H:i, 2019-06-18T11:00:00.000Z, 08:00 ); // 2019-06-18 19:00 date( Y-m-d H:i, 2019-06-18T11:00:00.000Z, 8 ); // 2019-06-18 19:00 date( Y-m-d H:i, 2019-06-18T11:00:00.000Z, 480 ); // 2019-06-18 19:00上面最后一个例子透露了一个细节数值timezone的单位是分钟。从源码可以看到数字偏移会被直接传给moment.utcOffset()而字符串则先经过正则/^[-][0-1]0-9?$/校验——只有形如08、08:00的 ISO 8601 偏移才会按偏移处理否则按 IANA 时区名处理见 buildMoment 与 isUTCOffset。gmdate始终在 UTC 下格式化gmdate( dateFormat, dateValue )对应 PHP 的gmdate()先把日期转换为 UTC 再格式化输出英文。它适合存储、日志或任何要求规范化的场景import { gmdate } from wordpress/date; gmdate( Y-m-d H:i, 2019-06-18T11:00:00.000Z ); // 2019-06-18 11:00无论站点时区如何结果都基于 UTC国际化格式化dateI18n 与 gmdateI18ndateI18n类似 wp_date()翻译为站点语言dateI18n( dateFormat, dateValue, timezone )与date()行为一致但会额外把结果翻译成站点当前 locale——星期、月份、上午/下午标识等都会使用settings.l10n中配置的本地化字符串。向后兼容说明第三个参数timezone若传true函数将直接委托给gmdateI18n即按 UTC 处理若传false等价于不传。官方注释明确指出boolean类型虽然在类型上仍被接受但“effectively deprecated”已实质废弃仅保留用于向后兼容新代码应使用字符串或数字。import { dateI18n } from wordpress/date; dateI18n( D j M Y, 2019-06-18T11:00:00.000Z, true ); // 站点 locale 为英语时 Tue 18 Jun 2019 // 若站点 locale 为西班牙语本地化数据中月份为 es_June 等 es_Tue 18 es_Jun 2019需要特别注意的是序号后缀如18th与 RFC 2822 输出始终是英文这与 PHPwp_date()的行为保持一致。这一点在 测试用例 中有明确注释说明比如dateI18n( l jS F Y, ... )得到es_Tuesday 18th es_June 2019——18th不被翻译。gmdateI18nUTC 本地化gmdateI18n( dateFormat, dateValue )是gmdate()的本地化版本固定使用 UTC 时区并应用站点 localeimport { gmdateI18n } from wordpress/date; gmdateI18n( D j M Y, 2019-06-18T11:00:00.000Z ); // 本地化后基于 UTC 输出Tue 18 Jun 2019站点为其他语言时星期/月份被翻译从 实现 可见gmdateI18n与gmdate的唯一区别是多了dateMoment.locale( settings.l10n.locale )一行将 locale 切换到站点配置。时区处理机制站点时区、WP 自定义时区与 UTC 偏移wordpress/date时区体系的核心在 实现源码 中可见settings.timezone.string优先若站点配置了 IANA 时区字符串如America/New_York所有缺省时区参数的调用都通过moment().tz( string )转换因此能正确处理夏令时——测试中2019-01-18T11:00:00Z在纽约输出06:00而2019-06-18T11:00:00Z输出07:00正是 DST 的体现否则退回固定 UTC 偏移站点只配置了偏移timezone.offset时使用moment().utcOffset( offset )此时冬夏输出一致都是07:00自定义WP时区模块在初始化时通过setupWPTimezone()把一个名为WP的虚拟时区注册进 moment-timezone。它要么克隆settings.timezone.string对应时区的完整abbrs/untils/offsets数据保留 DST 信息要么仅用settings.timezone.offset构造一个固定偏移时区。getDate、isInTheFuture、humanTimeDiff三个函数都以WP时区为基准工作WP时区自愈机制由于第三方插件如 WooCommerce可能加载自己的 moment-timezone 副本导致内部 zone 存储被重置、WP时区被销毁。源码因此实现了ensureWPTimezone()先检查moment.tz.zone( WP )是否存在不存在时用缓存的wpZonePacked字符串moment.tz.pack()的打包结果重新注册。对应地测试 通过直接删除moment.tz._zones.wp模拟插件冲突验证了getDate、isInTheFuture、humanTimeDiff在时区丢失后仍能正常恢复。这套设计保证了无论站点使用带 DST 的具名时区还是固定偏移编辑器中的时间展示都能与 PHP 侧完全一致。设置管理getSettings 与 setSettingsgetSettings读取当前日期设置getSettings()返回当前生效的DateSettings包含本地化数据、格式模板与时区配置。WordPress 核心通过wp_default_packages_inline_scripts()源码注释指明需与src/wp-includes/script-loader.php保持同步注入这些数据。setSettings按 wp_localize_script() 格式注入本地化setSettings( dateSettings )把 PHP 侧本地化出来的数据写入模块并注册到 moment 的 locale 系统若 moment 已存在同名 locale且longDateFormat( LTS )为null例如运行在 WordPress 6.0 的站点上则先删除这个“被错误配置”的 locale 再重建否则直接复用已有 locale创建 locale 时以英文为parentLocale只覆盖 months、monthsShort、weekdays、weekdaysShort、meridiem上午/下午标识、longDateFormat 与 relativeTime相对时间词这样缺失的词条自动回退到英文全程会备份并恢复 moment 的当前 locale避免副作用。DateSettings 的类型结构完整的类型定义见 packages/date/src/types.ts顶层分为三块type DateSettings { l10n: { locale: string; months: string[]; // 全年月份全称 monthsShort: string[]; // 月份缩写 weekdays: string[]; // 星期全称 weekdaysShort: string[]; // 星期缩写 meridiem: { am: string; AM: string; pm: string; PM: string }; relative: Recordstring, string; // 如 mm: %d 分钟, hh: %d 小时 startOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6; }; formats: { time: string; // 默认 g:i a date: string; // 默认 F j, Y datetime: string; // 默认 F j, Y g:i a datetimeAbbreviated: string; // 默认 M j, Y g:i a }; timezone: { offset: number; // 数值偏移分钟 offsetFormatted: string; // 带小数的偏移格式化为分钟 string: string; // IANA 时区名如 America/Los_Angeles abbr: string; // 时区缩写 }; };模块内置了一套英文默认设置locale: en、格式F j, Y等在setSettings()被调用前即可正常工作。辅助函数getDate、isInTheFuture 与 humanTimeDiff这三个函数全部以WP时区即站点时区为基准且都会先调用ensureWPTimezone()确保时区可用。getDateWP 时区字符串 → JS DategetDate( dateString )把“WP 时区下的日期字符串”转换为原生 JavaScriptDate对象。不传参数时返回“当前时刻在 WP 时区对应的 Date”import { getDate } from wordpress/date; getDate( 2024-01-15T10:00:00 ); // Date 对象内部先经 WP 时区解析再 toDate() getDate(); // 当前时间的 DateisInTheFuture判断是否在未来的计划中isInTheFuture( dateValue )将传入日期与“WP 时区下的当前时刻”比较返回布尔值。编辑器用它判断某篇内容是否处于“未来发布时间”从而决定是否显示“Scheduled”状态。测试还验证了它是时区无关的——即使把站点偏移改到未来时区判断结果也只取决于绝对时间见 测试用例。import { isInTheFuture, getDate } from wordpress/date; isInTheFuture( new Date( Number( getDate() ) 1000 * 60 ) ); // true1 分钟后 isInTheFuture( new Date( Number( getDate() ) - 1000 * 60 ) ); // false1 分钟前humanTimeDiff人类可读的时间差humanTimeDiff( from, to )对应 PHP 的human_time_diff()。to缺省时表示“从现在算起”返回诸如an hour ago、2 days ago、in 2 hours的相对时间短语文案来自 locale 的relative配置import { humanTimeDiff } from wordpress/date; humanTimeDiff( 2023-04-28T11:00:00.000Z, 2023-04-28T12:00:00.000Z ); // an hour ago humanTimeDiff( 2023-04-28T11:00:00.000Z, 2023-04-30T13:00:00.000Z ); // 2 days ago源码级原理PHP 格式符到 Moment.js 的完整映射format()之所以能直接使用 PHP 风格的格式串是因为 formatMap 维护了一张完整的映射表。下面按类别整理其中带“函数实现”的条目由源码中的函数动态计算而非简单映射日期日 / 周 / 月 / 年PHP含义映射d月中的日两位补零DDD星期缩写Mondddj月中的日不补零Dl星期全称MondayddddNISO 星期几1周一…7周日ES英文序号后缀st/nd/rd/th函数实现取Do再剔除数字w星期几0周日…6周六dz年内第几天从 0 起函数实现DDD - 1WISO 周数WF月份全称JuneMMMMm月份两位补零MMM月份缩写JunMMMn月份不补零Mt当月天数28~31函数实现daysInMonth()L是否闰年1/0函数实现isLeapYear()oISO 周纪年GGGGY四位年份YYYYy两位年份YY时间PHP含义映射a/A小写/大写上午下午标识a/ABSwatch 互联网时间.beats函数实现按 UTC1 换算秒数后除 86.4g/G12/24 小时制不补零h/Hh/H12/24 小时制补零hh/HHi分钟补零mms秒补零ssu微秒6 位SSSSSSv毫秒3 位SSS时区PHP含义映射e时区名称如 UTCzzI是否处于夏令时1/0函数实现isDST()O与 UTC 偏移hhmmZZP与 UTC 偏移hh:mmZT时区缩写zZ时区偏移秒数含正负号函数实现解析Z后换算为秒完整日期时间PHP含义映射cISO 8601YYYY-MM-DDTHH:mm:ssZYYYY-MM-DDTHH:mm:ssZrRFC 2822如Tue, 18 Jun 2019 11:00:00 0000函数实现强制英文 locale 后按ddd, DD MMM YYYY HH:mm:ss ZZ输出UUnix 时间戳秒X另外格式串中的\是转义符反斜杠后的下一个字符会作为字面量输出例如\Y输出字符Y而非年份这在源码format()的逐字符扫描中有明确处理。测试用例对18/6/19、Tuesday 18th June 2019、499Swatch 时间等边界输出都做了逐一断言可在 packages/date/src/test/index.js 中查阅完整对照。在编辑器中的实际使用在 Gutenberg 内部wordpress/date被广泛使用这从侧面印证了其 API 设计的目标场景。比较典型的调用点包括发布计划post-schedule编辑器的“立即发布 / 计划发布”控件使用dateI18n生成发布日期标签、用isInTheFuture判断内容是否已排期日期格式选择器date-format-picker块编辑器中的日期格式预览组件在 README 中说明了如何与date/dateI18n结合展示用户选择的格式发布时间选择器publish-date-time-picker区块发布时间面板直接依赖本包的格式化与时区能力。如果你在自己的 WordPress 插件或独立项目中需要“和 WordPress 后台一模一样”的日期表现直接复用本包即可保证前端与 PHP 侧date_i18n/wp_date输出一致。小结与注意事项选对函数要英文纯格式化用date/gmdate要跟随站点语言用dateI18n/gmdateI18nUTC 场景一律使用gm*前缀版本时区默认值所有函数缺省时都采用站点时区设置具名时区会正确处理夏令时固定偏移则全年一致timezone 参数类型字符串IANA 时区名或 ISO 8601 偏移、数字分钟、true/false历史兼容true等价于gmdateI18n均可但boolean已实质废弃数值0是合法的 UTC0 偏移不会被当作“未传参”此问题在 5.38.0 修复见 CHANGELOG格式串与 PHP 对齐完整的 PHPdate()格式符支持以及\转义保证从服务端迁移到前端的格式串无需改动环境要求ES2015必要时引入wordpress/babel-preset-default的 polyfill。掌握上述 API 与源码机制后无论是编辑器插件的时间 UI还是独立应用中的多语言日期展示都能借助wordpress/date获得与 WordPress 核心完全一致的行为。【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表