时区坑 moment() toDate() getTime()
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了时区坑 moment() toDate() getTime()相关的知识,希望对你有一定的参考价值。
参考技术A 在某业务中,需要取date的前60后30天范围date完全是标准的0时区日期格式:
在正时区不会出现问题,但是在负的时区如下,会取到第30天的前一天,因为浏览器location time需要相应的进行转换。
这是正常的接口时间转换,解决方法:
算取-60 +30的时间段时间戳,再减去相应的当地时区存在的时间差值,所以这样转换出来的时间,也永远是0点,跟 date 整差 -60 +30的天数。虽然这种事情前端解决很没必要,但是问题来了,总得处理。
使用 moment.js 检查本地时间是不是在其他 2 个时区时间之间
【中文标题】使用 moment.js 检查本地时间是不是在其他 2 个时区时间之间【英文标题】:Using moment.js to check if local time is between 2 other time zones times使用 moment.js 检查本地时间是否在其他 2 个时区时间之间 【发布时间】:2021-12-14 16:47:10 【问题描述】:有人提出了类似的问题,但无论出于何种原因,我都无法理解这一点。我希望世界上任何地方的用户都能看到我的网站上的商店是开门还是关门。商店的营业时间是周一至周五上午 8 点至晚上 8 点,周六至周日上午 8 点至晚上 7 点。
所以基本上代码需要获取用户本地时间并将其与 CT 中的当前时间进行比较,然后查看商店是否营业。如果它在周二晚上 7 点 CT 发生,则可能是远东时区的周三早上,所以现在您也需要比较这些日子。
我所做的所有搜索都发现了一些类似问题/答案的点点滴滴,但我就是不知道如何将它们放在一起以提出解决方案。我开始尝试这个:
var currTimeTokyo = moment.tz(moment(), 'Asia/Tokyo').format();
var currTimeCT = moment.tz(moment(), 'America/Chicago').format();
console.log(currTimeTokyo);
console.log(currTimeCT);
这给出了:
2021-10-30T00:51:42+09:00
2021-10-29T10:51:42-05:00
这些是正确的,但现在我如何比较今天的开放/关闭时间?我需要检查东京时间是否在 CT 的打开和关闭之间,但打开/关闭时间取决于它是哪一天,而且东京可能与 CT 不同的一天。您将如何解释所有这些?
更新:我发现了一些有用的东西并作为答案发布。
【问题讨论】:
【参考方案1】:我不知道 moment.js,而且我认为它已经被宣布弃用(day.js 或 luxon 将是当前的替代方案),所以我无法为您提供正确的语法,但我尝试帮助解决逻辑问题。
-
就像你说的,从用户那里获取当前本地时间
将其转换为商店所在的 CTtime。如果有星期二,则有星期二,根据您的商店营业时间,它是关闭还是营业。如果您检查的时区可能已经改变了日期,这并不重要
比较商店的当地时间和营业时间 - 现在是哪个工作日?是在开闭之间吗?
【讨论】:
谢谢!我研究了 Luxon,并提出了一些我认为可行的方法。我用新代码编辑了我的原始帖子。我想我想太多了,但是通过立即将本地时间转换为 CT,其余部分相对简单。也许在momentjs中有一种方法可以做到这一点,但我找不到它。 很高兴听到您使用 luxon 找到了解决方案,看起来不错!而不是修改您的问题(似乎已经回答),您可以在答案中写下这个并接受它。 (您仍然可以通过回滚您的编辑并在答案中发布新内容来做到这一点) 好电话。更新以反映这一点!【参考方案2】:我按照 Corrl 的建议调查了 Luxon,我想出了这个,我认为这解决了我的问题。
// open hours are M-F 8am-8pm, Sat-Sun 8am-7pm (all times CT)
var hours = [
day: 'Sunday', open:8, close:19 ,
day: 'Monday', open:8, close:20 ,
day: 'Tuesday', open:8, close:20 ,
day: 'Wednesday', open:8, close:20 ,
day: 'Thursday', open:8, close:20 ,
day: 'Friday', open:8, close:20 ,
day: 'Saturday', open:8, close:19
];
var isOpen = false;
var local = luxon.DateTime.local(); // get current time in local tz
var localInCT = local.setZone("America/Chicago"); // rezone to CT without changing timestamp;
hours.forEach(function(item, index)
if (index === localInCT.weekday && localInCT.hour >= item.open && localInCT.hour < item.close)
isOpen = true;
);
console.log(isOpen);
【讨论】:
我认为逻辑上没问题。您使用 'var' 而不是 'const/let' 有什么原因吗?我认为可以改进的一件事是,不要将小时作为数组,它总是使用 .forEach() 完全迭代,而是使用带有工作日数字的对象作为查找键或通过带有开关的函数检查打开。 This example 表达了我的意思。 请注意,根据luxon api docs,工作日数字是从“1 = 星期一”到“7 = 星期日” @Corrl 使用 var 因为这是对无法使用 ES6 的古老代码的修复。相信我,它也困扰着我。另外,感谢平日对指数的提醒。我只是假设它与 momentjs 相同并使用 Sun=0 - Sat=6。有趣的是,只有 Sunday 在 moment 和 luxon 之间确实有不同的索引,但在循环数组等方面它改变了一切。感谢您的示例,我认为在这种情况下,您使用带有查找键的对象而不是数组的解决方案更有意义!以上是关于时区坑 moment() toDate() getTime()的主要内容,如果未能解决你的问题,请参考以下文章
Moment.js - 显示选定范围内关于用户时区的历史数据