Javascript SetMonth 问题

Posted

技术标签:

【中文标题】Javascript SetMonth 问题【英文标题】:Javascript SetMonth Issue 【发布时间】:2021-11-09 16:30:46 【问题描述】:

我正在做单元测试。

  it("Month calculate", () => 
    const baseDate = new Date("2015-02-15T12:00:00.000Z");
    baseDate.setMonth(baseDate.getMonth() + 1)
    expect(baseDate.toISOString()).toBe("2015-03-15T12:00:00.000Z")
  )

在我的本地节点进程中出现此错误

Expected: "2015-03-15T12:00:00.000Z"
Received: "2015-03-15T13:00:00.000Z"

在 docker 节点进程上它可以工作。

我相信它与 DST 有关,但我不明白如何...

【问题讨论】:

您所在的时区。您认为 DST 会在 2 月 15 日至 3 月 15 日之间生效吗? @phuzi 我的时区是 GMT-3,“巴西利亚标准时间” @phuzi - 这很有趣。他们不再使用 DST,但直到 2019 年才使用,而 2015 年的变化是在 2 月 22 日 - timeanddate.com/time/change/brazil/brasilia?year=2015 :-) @T.J.Crowder - 事实上,还有很多问题。但问题似乎已解决。 【参考方案1】:

DST 开始发挥作用是对的,因为您使用的是 本地时间 setMonth/getMonth 方法,所以 DST 进入它(添加月份,@ 987654323@ 对象将 DST 考虑在内以避免更改时间;但是当您查看 UTC 的结果时,您会看到时间偏离了 DST 偏移量,因为它是应用于增量的本地时间数学) .要像其他代码一样使用 UTC,请改用 setUTCMonth/getUTCMonth

it("Month calculate", () => 
    const baseDate = new Date("2015-02-15T12:00:00.000Z");
    baseDate.setUTCMonth(baseDate.getUTCMonth() + 1)
    expect(baseDate.toISOString()).toBe("2015-03-15T12:00:00.000Z")
)

您的 docker 节点可能正在使用 UTC,或者至少在那个月 DST 不会改变的时区(例如,在英国不会改变;我们要到 3 月下旬才会改变) .但是在您当地的时区,显然 DST 发生在那个月,所以您在本地看到问题,但在 docker 节点上看不到。

【讨论】:

以上是关于Javascript SetMonth 问题的主要内容,如果未能解决你的问题,请参考以下文章

日期类 setMonth 设置奇怪的值

CalendarUtil.addMonthsToDate()和JsDate.setMonth()在GWT中给出错误的日期

一JavaScript获取当前月份的前12个月,获取最近的12个月二js实现获取当前月份前的12个月份,格式化后放在一个数组里

使用JavaScript制作页面特效2

JavaScript实现月份累加,比如‘2021-01-31‘加一个月得到‘2021-02-28‘

js日期