如何收集访问者的时区信息?
我两者都需要:
时区(例如,欧洲/伦敦) 与UTC或GMT的偏移(例如,UTC+01)
如何收集访问者的时区信息?
我两者都需要:
时区(例如,欧洲/伦敦) 与UTC或GMT的偏移(例如,UTC+01)
当前回答
为什么不直接使用:
function timezoneOffset(date: Date) {
return 6000 * ((date.getUTCHours() - date.getHours()) * 60 + ((date.getUTCMinutes() - date.getMinutes())))
}
其他回答
尝试Date对象的getTimezoneOffset():
var curdate = new Date()
var offset = curdate.getTimezoneOffset()
此方法返回时区偏移量(以分钟为单位),即GMT和本地时间之间的差值(以分钟为单位)。
为什么不直接使用:
function timezoneOffset(date: Date) {
return 6000 * ((date.getUTCHours() - date.getHours()) * 60 + ((date.getUTCMinutes() - date.getMinutes())))
}
使用偏移量来计算时区是一种错误的方法,您总是会遇到问题。时区和夏令时规则可能会在一年中发生几次变化,并且很难跟上变化。
要获得JavaScript格式的系统IANA时区,您应该使用
控制台日志(Intl DateTimeFormat resolvedOptions()()。timeZone)
截至2023年2月,全球93.75%的浏览器都能正常运行。
旧的兼容性信息
ecma-402/1.0说timeZone如果没有提供给构造函数,可能是未定义的。然而,未来的草案(3.0)通过更改系统默认时区修复了这个问题。
在此版本的ECMAScript国际化API中, 如果没有timeZone属性,则timeZone属性将保持未定义 提供在提供给Intl的options对象中。DateTimeFormat 构造函数。但是,应用程序不应该依赖于此,因为未来 版本可能返回一个String值,用于标识主机环境 改为当前时区。
在ecma-402/3.0草案中,它被改成了
在此版本的ECMAScript 2015国际化API中 如果没有,timeZone属性将是默认时区的名称 属性在options对象中提供 Intl。DateTimeFormat构造函数。上一版本的 timeZone属性在本例中未定义。
这个问题已经有30多个答案了,但我敢肯定,有些人来到这里,却真的不知道他们在寻找什么。
惊喜!你要打开一个棘手的罐子了!
我强烈推荐你阅读我最近写的一篇关于在JS中处理时区的头痛的文章!https://medium.com/@EyeDin/time-and-time-zone-headaches-in-javascript-ae4d873a665d
你到底在找什么?
根据您的实际用例,您实际上需要不同的东西。
1)一种将固定时间点(比如2021年11月13日旧金山晚上11:35:21)转换为用户的挂钟时间的方法,用户可能在世界上任何地方。
使用.toLocaleString()。
通过DateTimeFormat中列出的locale和选项两个参数,它有更多用于格式化的自定义参数。它甚至支持不同的日历、语言、年、月、日等格式(没有传递的参数将使用用户的默认设置,这可能是最理想的)。
作为开发人员,只需将该时间点值(例如,Sales活动或竞赛的开始时间)作为UNIX时间戳数(即UTC从1/1/1970开始的秒数,与时区无关,与dst0无关)传递给客户机,然后执行new Date(timestamp). tolocalestring()。例如,对于上面的时间点,值是1636875321000(毫秒),via +dateWithTimeZone("America/Los_Angeles",2021,10,13,23,35,21)使用这个答案的函数。
2)能够在3个月后的当地时间上午9点向用户发送通知/电子邮件
这是一个完全不同的要求!非常非常不同!
格林尼治时间8点还不够吗?
No!
这只是用户在某个时间点所在的时区,比如“现在,今天”。
您如何知道用户是否使用日光节约时间?(美国的亚利桑那州没有,其他很多国家、州甚至县都没有!) 您如何知道用户是在DST中还是不在DST中?旧金山是冬天(GMT-8)还是阿拉斯加是夏天(同样是GMT-8) ?看看这个巨大的列表,你会抓狂的:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
“PDT”还不够吗?
No!
首先,PDT并不是全年都有的。现在是11月,timeanddate.com网站上写着“PDT目前没有位置。你想看PST吗?”(阅读我上面的Medium文章了解更多细节。)
除非你想要从客户端到客户端的UI字符串,这个PDT/CEST/等等。一点价值都没有!
为什么?因为墨西哥的蒂华纳和美国的旧金山在6月都在PDT,但他们有不同的DST(日光节约)日,他们切换到PST。你需要知道这一点!
美国2022年夏令时为2022年3月13日至11月6日。墨西哥2022年的夏令时时间为2022年4月3日至2022年10月30日。因此,虽然蒂华纳和旧金山在近93%的时间里共享“PDT/PST”,但在7%的时间里(例如,2022年的3月14日至4月3日,以及10月31日至11月6日),它们并不匹配。
所以,即使你知道现在是11月,也知道用户处于PDT状态,你也无法判断用户设备中的时间戳数字是2022年4月1日上午9点。
PS.如果你试图从new Date(). tostring()中获取PDT,情况会更糟。仅供参考,如果你将你的机器的语言环境更改为es-MX(西班牙语,这是13%的美国人的语言),你会得到这样的结果:
> new Date().toString()
'Sun Nov 14 2021 00:47:25 GMT-0800 (hora estándar del Pacífico)'
祝hedP好运!
那么,我该怎么办呢?
唯一正确的方法是使用IANA(阅读“标准”)时区值。这是维基百科页面的第二栏。它来自:
const timeZoneIANA = Intl.DateTimeFormat().resolvedOptions().timeZone;
它返回IANA值,即旧金山的America/Los_Angeles。如果有的话,这是您应该为用户存储在数据库中的值。您可以从时区获得关于它的各种信息。Json包,并将时间从/转换为该时区,加上日期(这很重要),就像这个答案。
那么IE11呢?
IE11不支持Intl....事情大多数填充物只是猜测,是不准确的。所以,试着放弃对IE11的支持,或者使用一个库,为一些不准确做好准备。
3)我只是想知道他们目前的时区偏移(例如-8:00)
你可能不应该这么做。我想不出你需要这个的真正原因。再说一次,知道今天的值,并不能告诉你明天的值是多少。
不管怎样,你总能得到这个值
new Date().getTimezoneOffset() / 60
在客户端。
注意:. gettimezoneoffset()不是date对象的时区偏移量,你是在调用它。请阅读文档。
准确地说,它接受传递的Date对象(该对象具有时间戳,引用历史中的单个时间点),然后告诉该时间点的UTC时间和本地时间之间的差值。
同样,这取决于日期。看到的:
console.log(new Date("6/13/2021").getTimezoneOffset() / 60); // It's 7 on a machine that runs in San Francisco
console.log(new Date("11/13/2021").getTimezoneOffset() / 60); // It's 8 on a machine that runs in in San Francisco
有图书馆吗?
下面是支持时区交换的库列表。
但是,请记住,您必须首先解决设计问题,然后再寻找代码。关于时区的事情很容易变得复杂,你必须知道“PDT”和“GMT-8”不是全年为用户存储在DB中的有信息/有价值的时区值。:)
你可以简单地试试这个。 它将返回您当前的机器时间
var _d = new Date(), T = 0, d = new Date(t*1000 + _d.getTime())