You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现通用夏令时(DST)校验函数,解决CI环境运行失败问题

问题根源

你当前的代码出现本地运行正常、CI失败的核心原因是:原生Date.prototype.getTimezoneOffset()方法返回的是代码运行环境本地时区相对于UTC的偏移量,和你用toDate指定的时区完全无关。你本地环境时区恰好是Europe/Amsterdam所以测试通过,CI环境默认时区通常为UTC,自然返回错误结果。

解决方案

调整isDST函数,增加时区入参,使用date-fns-tz提供的tzOffset方法计算指定时区的偏移量,完全脱离运行环境时区的影响。

完整修改后代码

import { toDate, tzOffset } from "date-fns-tz"
import { parseISO, getYear } from "date-fns"

/**
 * 校验指定时区下的给定日期是否处于夏令时
 * @param {Date|string|number} date 待校验的日期
 * @param {string} timeZone 目标时区IANA标识,例如 Europe/Amsterdam
 * @returns {boolean} 目标日期在指定时区是否处于夏令时
 */
export function isDST(date, timeZone) {
  const year = getYear(date)
  // 计算指定时区当年1月1日的偏移量
  const januaryOffset = tzOffset(timeZone, new Date(year, 0, 1))
  // 计算指定时区当年7月1日的偏移量
  const julyOffset = tzOffset(timeZone, new Date(year, 6, 1))
  // 计算指定时区下待校验日期的偏移量
  const currentOffset = tzOffset(timeZone, date)

  // 偏移量最大值对应冬令时,二者不等则为夏令时
  return Math.max(januaryOffset, julyOffset) !== currentOffset
}

// 调整后的测试用例
it("returns true if dst applies", () => {
  const targetTz = "Europe/Amsterdam"
  const date = toDate(parseISO("2021-03-28 02:00:00"), {
    timeZone: targetTz,
  })

  expect(isDST(date, targetTz)).toEqual(true)
})

it("returns false if dst does not apply", () => {
  const targetTz = "Europe/Amsterdam"
  const date = toDate(parseISO("2021-10-31 03:00:00"), {
    timeZone: targetTz,
  })

  expect(isDST(date, targetTz)).toEqual(false)
})

说明

  • 调整后的函数为通用实现,传入任意IANA标准时区标识即可校验对应时区的夏令时状态,不受运行环境时区影响,CI环境可以正常通过测试。
  • 如果你固定使用某一个时区,也可以给isDST的timeZone参数设置默认值,无需每次调用都传参。

内容的提问来源于stack exchange,提问作者user15485638

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:33:03