
Luxon 升级指南从 1.x / 2.x 迁移到 3.0 的破坏性变更全解析【免费下载链接】luxon⏱ A library for working with dates and times in JS项目地址: https://gitcode.com/gh_mirrors/lu/luxonLuxon 是专为 JavaScript 设计的日期与时间处理库提供了DateTime、Duration、Interval等不可变、可链式调用的 API并原生支持时区与Intl。本文基于仓库中的 docs/upgrading.md完整梳理 Luxon 从 1.x 到 2.0、再到 3.0 的全部破坏性变更读完你不仅能逐条对照迁移存量代码还能理解system 与 default 时区语义fromObject 双参数签名Settings.defaultZone 重构等变更背后的源码实现原理以及如何用仓库内的测试用例验证迁移结果。一、3.0 的唯一破坏性变更system 时区语义修正Luxon 3.0 只引入了一个破坏性变更当以字符串system指定时区时始终解析为运行环境的系统时区SystemZone与全局默认时区设置无关。而要想拿到当前默认时区无论它被设置成什么必须显式使用defaultSettings.defaultZone America/Chicago; DateTime.now().setZone(default) // 结果是芝加哥时间America/Chicago DateTime.now().setZone(system) // 使用用户机器的系统时区如果觉得这个语义理所当然请务必注意在 3.0 之前它并不是这样工作的——这正是它被列为破坏性变更的原因。在旧版本中system的表现受默认时区影响行为不一致3.0 将其固定为系统时区并新增default作为跟随默认设置的显式关键字。源码印证normalizeZone 中的关键字分流system与default的分流逻辑位于 src/impl/zoneUtil.js 的normalizeZone()函数中if (lowered default) return defaultZone; else if (lowered local || lowered system) return SystemZone.instance; else if (lowered utc || lowered gmt) return FixedOffsetZone.utcInstance; else return FixedOffsetZone.parseSpecifier(lowered) || IANAZone.create(input);可以看到default命中第一分支返回的是传入的defaultZone即Settings.defaultZone的当前值而system与遗留的local都会命中第二分支直接返回SystemZone.instance单例从而彻底与默认时区解耦。SystemZone的实现位于 src/zones/systemZone.js它通过单例模式暴露instance其type恒为systemname由new Intl.DateTimeFormat().resolvedOptions().timeZone动态获取即浏览器/Node 所在机器的系统时区名偏移量由-new Date(ts).getTimezoneOffset()计算isValid恒为true。测试印证系统时区与默认时区被严格区分仓库测试 test/datetime/zone.test.js 中有多组用例专门验证这一语义DateTime#setZone accepts system and uses the system zone断言DateTime.utc().setZone(system).zoneName等于Settings.defaultZone.name系统时区名DateTime#setZone accepts default and uses the default zone在Helpers.withDefaultZone(Europe/Paris, ...)包裹下断言setZone(default).zoneName Europe/ParisSetting the default zone to system gives you back the system zone先设置Settings.defaultZone Asia/Tokyo再改回system断言DateTime.local().zoneName恢复为系统时区名。这三组用例恰好对应 3.0 语义修正后应当成立的行为迁移时可以仿照它们为你的代码补上回归测试。二、2.0 的破坏性变更总览Luxon 2.0 是一轮更大规模的 API 重构破坏性变更主要分为三类环境支持收紧、方法签名统一、时区命名澄清。下面逐项展开。三、环境支持收紧与 polyfill 构建移除Luxon 2.0 起不再支持 Node 12也不再支持任何版本的 IE仅支持较新版本的主流浏览器。这一决策让 Luxon 可以在代码中大胆假设环境能力例如Intl、原生时区支持等从而大幅简化内部实现。与此对应官方不再提供 polyfill 版本构建——Luxon 依赖的所有能力在目标浏览器中均已原生可用。具体支持范围可参考 docs/matrix.mdSupport Matrix。这意味着如果你的项目仍需要兼容老 IE 或超低版本 Node需要自行评估并停留在 1.x 版本。四、方法签名变更fromObject 双参数化2.0 起DateTime.fromObject()与Duration.fromObject()统一改为接受两个参数第一个是字段对象第二个是选项对象。此前混在同一个对象里的时区、语言等配置项必须拆出来// Luxon 1.x DateTime.fromObject({ hour: 3, minute: 2, zone: America/New_York, locale: ru }); Duration.fromObject({ hours: 3, minutes: 2, conversionAccuracy: casual, locale: ru }); // vs Luxon 2.x DateTime.fromObject({ hour: 3, minute: 2 }, { zone: America/New_York, locale: ru }); Duration.fromObject({ hours: 3, minutes: 2 }, { conversionAccuracy: casual, locale: ru });源码印证fromObject 的选项解析路径在 src/datetime.js 中DateTime.fromObject(obj, opts {})的第一步就是通过normalizeZone(opts.zone, Settings.defaultZone)解析选项里的时区再通过Locale.fromObject(opts)构造本地化配置。也就是说zone、locale等配置只能来自第二个参数opts混在字段对象里的旧写法在 2.x 下将不再生效。Duration.fromObject的选项同样独立承载在 src/duration.js 中conversionAccuracy选项决定采用哪一套换算矩阵——longterm长期平均还是默认的casual按每月 30 天、每年 365 天等近似换算并在 src/duration.js 的构造函数中据此选择accurateMatrix或casualMatrix。五、toLocaleStringIntl 选项与 DateTime 配置分离在 1.x 中toLocaleString()允许把Intl.DateTimeFormat的格式化选项与locale之类的 DateTime 配置混在同一个 options 参数里。2.0 起拆成两个参数第一个参数为 Intl 格式化选项或 Luxon 预设常量第二个参数为 DateTime 配置覆盖项// Luxon 1.x DateTime.now().toLocaleString({ hour: 2-digit, locale: ru }); // vs Luxon 2.x DateTime.now().toLocaleString({ hour: 2-digit }, { locale: ru });源码印证双参数的实际消费方式在 src/datetime.js 中toLocaleString(formatOpts Formats.DATE_SHORT, opts {})用this.loc.clone(opts)把第二个参数并入实例的本地化配置再用Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this)完成格式化。从源码结构看formatOpts只负责传给Intl.DateTimeFormat层面的呈现样式而locale、numberingSystem、outputCalendar等行为性配置统一经由opts注入——二者职责边界清晰也正是迁移时最容易踩坑的地方记得把locale从格式化选项对象中挪到第二个参数。六、时区命名澄清local 更名为 system2.0 将运行环境的时区即运行 Luxon 的电脑/浏览器所设置的时区从local更名为system以消除歧义避免与本地时间的日常语义混淆DateTime.fromObject({}, { zone: local }) // 仍然可用向后兼容 DateTime.fromObject({}, { zone: system }) // 推荐写法 DateTime.fromObject({}, { zone: system }).zone // 类型为 SystemZone DateTime.fromObject({}, { zone: system }).zone.type // system这一点与第一节中 3.0 的语义修正是同一条主线的延续local作为system的别名在 src/impl/zoneUtil.js 中继续被接受但语义始终指向SystemZone.instance。七、Settings.defaultZone 重构与 defaultZoneName 移除2.0 清理了Settings.defaultZone的取值与赋值语义统一为写时可传字符串或 Zone 实例读时恒返回 Zone 实例// 赋值 Settings.defaultZone America/New_York; // 可以是字符串 Settings.defaultZone IANAZone.create(America/New_York); // 也可以是 Zone 实例 // 读取 Settings.defaultZone // 总是返回一个 Zone 实例最显著的破坏性变更Settings.defaultZoneName这个属性彻底不复存在。迁移时所有读取Settings.defaultZoneName的代码都要改为读取Settings.defaultZone.nameZone 实例的name属性或直接使用返回的 Zone 实例。源码印证defaultZone 的读写实现在 src/settings.js 中static set defaultZone(zone) { defaultZone zone; } static get defaultZone() { return normalizeZone(defaultZone, SystemZone.instance); }可见存储层只是保留原始值字符串、Zone 实例或system而读取时统一经normalizeZone归一化为 Zone 实例模块级初始值defaultZone systemsrc/settings.js也印证了默认默认值就是系统时区。normalizeZone对字符串的解析顺序default→system/local→utc/gmt→ 固定偏移 → IANA 时区直接决定了Settings.defaultZone接受哪些合法输入详见 src/impl/zoneUtil.js。另外注意setZone()方法内部同样调用normalizeZone(zone, Settings.defaultZone)src/datetime.js所以default关键字在setZone与Settings.defaultZone两条路径上的语义是一致的。八、其他破坏性变更清单除了上述大项2.0 还有一批小规模但会影响编译或运行结果的变更迁移时应逐条排查变更项1.x2.xtoObject的配置输出DateTime#toObject({ includeConfig: true })可附带配置includeConfig选项被移除不再支持本地化解析结果方法名resolvedLocaleOpts()更名为resolvedLocaleOptions()Zone 的通用性判断属性Zone#universal更名为Zone#isUniversal其中toObject()的实现位于 src/datetime.jsopts.includeConfig分支在 2.0 中被移除仅保留纯粹的日历字段输出resolvedLocaleOptions()的实现在 src/datetime.js返回{ locale, numberingSystem, outputCalendar }三元组isUniversal则定义在抽象基类 src/zone.js 上各子类如SystemZone、FixedOffsetZone、IANAZone分别覆写。九、非破坏性变更local/utc 获得选项参数作为配套增强DateTime.local()与DateTime.utc()在 2.0 起也支持在末尾传入一个 options 参数来设置zone与locale与fromObject()保持一致。它们的实现位于 src/datetime.js通过lastOpts(arguments)从参数列表末尾剥离选项对象DateTime.utc()还会强制opts.zone FixedOffsetZone.utcInstance。示例DateTime.local(2017, 3, 12, { locale: fr }); // 2017-03-12T00:00:00法语 locale DateTime.utc(2017, 3, 12, 5, 45, { locale: fr }); // 2017-03-12T05:45:00Z法语 locale十、版本演进脉络与迁移建议从源码和官方文档docs/upgrading.md可以看出Luxon 2.0 的变更目标高度聚焦统一选项参数的放置位置、澄清时区语义、简化环境支持假设。正如原文档所述Luxon 团队原本对 2.0 有更宏大的规划TypeScript 移植、错误处理重构等但因浏览器演进速度与维护精力的现实约束最终只落地了这一组为后续演进腾出操作空间的基础变更。这与当前仓库仍在持续推进的事实相符READMEREADME.md中正公开征集 Luxon 4.0 的路线图反馈。给存量项目的最终迁移清单若用到Settings.defaultZoneName改为Settings.defaultZone.name把fromObject/toLocaleString中混入的配置项zone、locale、conversionAccuracy等拆分到第二个参数将Zone#universal改为Zone#isUniversal、resolvedLocaleOpts改为resolvedLocaleOptions移除toObject({ includeConfig: true })的调用检查所有local字符串业务语义是系统时区就改写成system语义是跟随默认设置就改写成default确认运行环境满足 2.0 的要求Node ≥ 12、现代浏览器、无需 polyfill 构建参考 test/datetime/zone.test.js 中的断言模式为时区相关迁移补充回归测试。关于每个变更的完整 API 行为细节可继续查阅仓库内的 docs/calendars.md、docs/zones.md、docs/settings.md 相关章节 等文档以及 src/datetime.js、src/duration.js、src/settings.js 等源码。【免费下载链接】luxon⏱ A library for working with dates and times in JS项目地址: https://gitcode.com/gh_mirrors/lu/luxon创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考