temporal.plainyearmonth 专为账期设计,只存年月、不涉日期时区、无隐式归一化,创建时严格校验月份1–12,加减运算按日历规则进位,语义清晰可控。

用 Temporal.PlainYearMonth 处理账期,能彻底避开传统 Date 的“月份从 0 开始”和跨年自动归一化陷阱——它只存年份和月份,不绑定日期、不涉及时区、不隐式修正,语义干净,计算可控。
为什么账期管理特别需要 PlainYearMonth
账期本质是“某年某月”,比如「2026年4月账期」「2025年12月结账周期」。它不关心具体哪一天,更不需要时间戳或时区。而 new Date(2026, 3) 这种写法: - 月份传 3 实际表示 4 月,反直觉; - 若传错为 new Date(2026, 12),会静默变成 2027 年 1 月,掩盖逻辑错误; - toLocaleDateString() 等方法还会因本地时区干扰输出格式。
PlainYearMonth 则强制你明确表达「就是 2026 年 4 月」,且所有操作都围绕年月展开,无歧义。
创建与校验:一步到位,拒绝越界
构造时直接传真实年份和月份(1–12),非法值立刻报错:
-
✅ 正确:
Temporal.PlainYearMonth.from({ year: 2026, month: 4 }) -
❌ 报错:
Temporal.PlainYearMonth.from({ year: 2026, month: 0 })→ RangeError -
❌ 报错:
Temporal.PlainYearMonth.from('2026-13')→ RangeError
这种严格性对账期系统至关重要:录入「2026-13」不是“下一年 1 月”,而是数据异常,必须拦截。
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
跨年度加减:自然、可预测、不跳变
调用 .add() 或 .subtract() 时,PlainYearMonth 按日历规则进位,不依赖毫秒偏移:
-
ym = Temporal.PlainYearMonth.from('2026-04').add({ months: 9 })→2027-01 -
ym.subtract({ years: 1, months: 2 })→ 年月分别运算,结果确定 - 不会出现 Date 那种「加 30 天 ≈ 加 1 个月但有时多有时少」的模糊行为
账期滚动(如每月生成上月账单)可写成:const lastMonth = currentMonth.subtract({ months: 1 }),逻辑清晰,无需查当月天数。
与账期业务强关联的实用技巧
• 判断是否为当前账期:currentMonth.equals(Temporal.Now.plainYearMonthISO())
• 生成账期范围(起止日):const start = ym.toPlainDate({ day: 1 });const end = ym.add({ months: 1 }).toPlainDate({ day: 1 }).subtract({ days: 1 });
→ 安全得出「2026-04-01 至 2026-04-30」
• 数据库存储建议:
用 ym.toString()(如 "2026-04")存字段,比存 Date 对象或时间戳更直观、易索引、无时区污染。










