如何在Javascript中使用Temporal检查夏令时?

问题描述 投票:0回答:2

如果我有一个日期并且我想检查时间是否是夏令时,我可以使用一种方法,如下所示:

function isDST(d) {
  let jan = new Date(d.getFullYear(), 0, 1).getTimezoneOffset();
  let jul = new Date(d.getFullYear(), 6, 1).getTimezoneOffset();
  return Math.max(jan, jul) != d.getTimezoneOffset();    
}

(来源此处

如果我使用 MomentJS 库,我会以这种方式达到相同的效果:

moment().isDST();

有人知道如何对即将推出的 Temporal 做同样的事情吗?

javascript date momentjs dst ecmascript-temporal
2个回答
3
投票

我建议不要这样做,至少不要以这种形式。

除了评论中提到的爱尔兰示例之外,还有其他时区司法管辖区,由于 DST 以外的其他原因,与 UTC 的偏移量会发生一次性或非半年的变化,并且任何可能的

isDST()
实施都将,根据定义,这些情况下会发生故障。另一个例子是摩洛哥除斋月外全年都实行夏令时。对于世界上大多数人来说,“DST”根本没有任何意义。

为了解决这个问题,我首先要问您将使用这些信息做什么?

例如,如果要以时区名称指定“夏令时”或“标准”时间,您可以将

Intl.DateTimeFormat
{ timeZoneName: 'long' }
选项一起使用,这将为您提供时间名称包含此信息的区域。

如果您需要它作为 Moment 的

isDST()
方法的直接替代品,以便您可以将现有系统从 Moment 移植到 Temporal,我建议完全重新实现 Moment 函数,并计划放弃这个概念未来的“是 DST”。 (请注意,Moment 文档 也将此函数描述为一种 hack,有时无法提供正确的信息。)

Moment 函数的主体可以在 here 找到,而 Temporal 的等价函数是:

function isDST(zdt) {
    return (
        zdt.offsetNanoseconds > zdt.with({ month: 1 }).offsetNanoseconds ||
        zdt.offsetNanoseconds > zst.with({ month: 6 }).offsetNanoseconds
    );
}

您可能需要此信息的另一件事是与其他系统交互,这些系统在其数据模型中包含“is DST”位(这是一个不正确的概念,但您可能别无选择。)在这种情况下,我' d 建议将“is DST”函数限制为已知采用“DST”概念的允许时区列表,并在其他情况下返回 false,这至少应该过滤掉一些误报。

if (!listOfTimeZoneIDsWithDST.includes(zdt.timeZoneId))
  return false;

1
投票

时间 api 有一个

offsetNanoseconds
read-only
属性

zdt = Temporal.ZonedDateTime.from('2020-11-01T01:30-07:00[America/Los_Angeles]');
zdt.offsetNanoseconds;
  // => -25200000000000

还有

with
方法,它返回一个新对象,指定字段被覆盖。

我必须承认我还没有测试过它,但这样的东西基本上应该相当于你的功能。 (月份索引从1开始)

function isDST(d) {
  let jan = d.with({month: 1}).offsetNanoseconds ;
  let jul = d.with({month: 7}).offsetNanoseconds ;

  return Math.min(jan, jul) != d.offsetNanoseconds ;    
}

分区日期时间

完善开发

网络开发简化

© www.soinside.com 2019 - 2024. All rights reserved.