用 momentJS 正确处理 DST 偏移

Posted

技术标签:

【中文标题】用 momentJS 正确处理 DST 偏移【英文标题】:Correctly treating DST shift with momentJS 【发布时间】:2017-05-19 18:39:45 【问题描述】:

我遇到了一些我认为是正确的事情,但现在仔细观察显然是错误的。

我正在进行一个药丸提醒应用程序的项目,有人可以在其中设置通知以提醒他/她在正确的时间服用药丸。有些药物可以让一个人终生服用。在这种情况下,我多年不设置警报,我设置了最多 3 个月,当他拿了一个并将其标记为完成时,我设置了另一个警报,从那个日期/时间开始 3 个月后。

此应用仅在巴西发布,我们这里有夏令时。当它转换到 DST 时间时,时钟必须调整到午夜后的 -1 小时,当离开 DST 时它会增加 1 小时。

对于这个项目,我使用 Firebase、Ionic 2、LocalNotification 插件和 Moment JS。

我必须为用户制作一个故事,因为其他用户可以看到他是否正确使用它,所以我使用 Moment JS 来操作日期时间并保存通知并在 UNIX 时间的 firebase 中为该用户创建一个节点。

让我们终于解决问题了。

保存日期时,我会检查该日期是否为 DST,如果是,则添加 +3 小时,如果不是,则添加 +2。我需要添加它,因为当我将 isoString 包装在 Moment() 函数中时,它会给我 -3 小时或 -2 小时(尚未搜索过,但我认为 Moment 使用美国时间)。

如果我在 DST 时间内保存日期,如果我在 DST 时间内保存日期,这很好用,如果在某些情况下我不在 DST 上并保存 DST 时间天的通知,它会节省 +2 小时。

一个例子

DST 时间将在 10 月 15 日更改为 in DST。如果我需要保存 30 条通知,每天上午 12 点,从 10 月 1 日到 10 月 30 日。从第 1 天到第 15 天,日期将为对,从第 16 天到第 30 天,他们将有 +2 小时的时间。

这是我使用的基本代码:

// THIS'LL SET MY DATEPICKER TO THE DATE/HOUR I'M IN.
minDate: any = Moment().isDST ? Moment().subtract(3, 'h').toDate().toISOString() : Moment().subtract(2, 'h').toDate().toISOString();

// THIS'LL CONVERT THE SELECTED DATE TO A UNIX TIME IN WICH I'LL USE TO SAVE THE NOTIFICATION AND THE MEDICATION DATA ON FIREBASE
unixConverted = Moment(this.minDate).isDST ? Moment(this.minDate).add(3, 'h').unix() : Moment(this.minDate).add(2, 'h').unix();

奇怪的是,单独使用 Moment().unix() 它会给我正确的时间,如果我使用 Moment(this.minDate).unix() 它会给我选择的小时 -2 或 -3 小时。

因此,如果它在 DST 中(我将时钟设置为 -1 小时),我加 3,否则我加 2。

那么,如何正确操作 DST 转变? 有没有比使用 DST 更好的方法? 我使用这个逻辑是对的还是比我想象的要复杂得多?

【问题讨论】:

【参考方案1】:

好的,所以我找到了一个更好的方法,而不使用.isDST() 方法。

简单使用Moment().add(Moment().utcOffset(), 'm'),这将获取当前时刻时间并以分钟为单位添加偏移量。

.add().subract() 方法使 Moment 返回 UTC 时间。

utcOffset() 从 UTC 返回正数或负数分钟数(表示小时数),例如 -60 或 180。所以我会得到正确的时间偏移。

对我来说就像一个魅力。

【讨论】:

以上是关于用 momentJS 正确处理 DST 偏移的主要内容,如果未能解决你的问题,请参考以下文章

在 momentjs 中处理 DST 的问题

为啥 pytz 在跨越 TZ 和 DST 边界而不是 TZ 名称时正确调整时间和偏移量?

Pytz 在没有 DST 的情况下将时间转换为 UTC

哪个 JS 日期时间选择器正确处理 DST 转换?

使用本地时区在 Python 中获取正确的时区偏移量

如何在 Typescript 中正确导入 MomentJS 以解决以下错误:“Type 'typeof moment' 没有兼容的调用签名。” [复制]