如何收集访问者的时区信息?
我两者都需要:
时区(例如,欧洲/伦敦) 与UTC或GMT的偏移(例如,UTC+01)
如何收集访问者的时区信息?
我两者都需要:
时区(例如,欧洲/伦敦) 与UTC或GMT的偏移(例如,UTC+01)
当前回答
这就是我的解决方案:
// For time zone:
const timeZone = /\((.*)\)/.exec(new Date().toString())[1];
// Offset hours:
const offsetHours = new Date().getTimezoneOffset() / 60;
console.log(`${timeZone}, ${offsetHours}hrs`);
其他回答
这可能不是最优雅的解决方案,但却是最通用的。
这使用了Intl的timeZoneName属性。DateTimeFormat
function getTimeZone(zoneName = "long") { // set up formatter let formatter = new Intl.DateTimeFormat(undefined, { timeZoneName: zoneName }); // run formatter on current date return formatter.formatToParts(Date.now()) // extract the actual value from the formatter, only reliable way i can find to do this .find(formatted => formatted.type === "timeZoneName")['value']; } // console.log every type for (const zoneName of ['short', 'long', 'shortOffset', 'longOffset', 'shortGeneric', 'longGeneric']) { console.log(`${zoneName}: ${getTimeZone(zoneName)}`) } /* short: CDT long: Central Daylight Time shortOffset: GMT-5 longOffset: GMT-05:00 shortGeneric: CT longGeneric: Central Time */
这不仅得到格式化的GMT偏移时间(即GMT-5),还得到时区的口语化名称(即中央日光时间)。
这个方法唯一不做的是获取IANA时区。我推荐上面的答案。
据我所知,DateTimeFormat没有自定义格式化的方法,因此使用formattpart,这似乎是获得时区的唯一可靠方法。
值得注意的是,目前的ECMAscript规范中只有short和long被正式定义,其他4个选项只是标准提议的一部分,在撰写本文时,safari中明显没有,尽管它正在进行中
使用偏移量来计算时区是一种错误的方法,您总是会遇到问题。时区和夏令时规则可能会在一年中发生几次变化,并且很难跟上变化。
要获得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属性在本例中未定义。
同时给出偏移量和时区的一行程序就是在一个新的Date对象上调用toTimeString()。中数:
toTimeString()方法以美国英语的人类可读形式返回Date对象的时间部分。
问题是时区不是标准的IANA格式;它比IANA“大洲/城市”格式更方便用户使用。试试吧:
.toTimeString console.log(新日期()().slice (9)); .resolvedOptions console.log (Intl.DateTimeFormat () () .timeZone); console.log(new Date().getTimezoneOffset() / -60);
现在在加利福尼亚,toTimeString()返回太平洋夏令时,而Intl API返回美国/洛杉矶。在哥伦比亚,你可以使用哥伦比亚标准时间,而不是美国/波哥大标准时间。
请注意,这个问题的许多其他答案都试图通过调用Date.toString()来获取相同的信息。这种方法并不可靠,正如MDN解释的那样:
Date instances refer to a specific point in time. Calling toString() will return the date formatted in a human readable form in American English. [...] Sometimes it is desirable to obtain a string of the time portion; such a thing can be accomplished with the toTimeString() method. The toTimeString() method is especially useful because compliant engines implementing ECMA-262 may differ in the string obtained from toString() for Date objects, as the format is implementation-dependent; simple string slicing approaches may not produce consistent results across multiple engines.
时区(小时)-
var offset = new Date().getTimezoneOffset(); 如果(抵消< 0) console.log("您的时区是- GMT+" + (offset/-60)); 其他的 console.log("您的时区是- GMT-" + offset/60);
如果你想要像你在评论中提到的那样精确,那么你应该这样尝试-
var offset = new Date().getTimezoneOffset(); 如果(偏移<0) { var extraZero = “”; if(-offset%60<10) extraZero=“0”; console.log( “Your timezone is- GMT+” + Math.ceil(offset/-60)+“:”+extraZero+(-offset%60)); } 还 { var extraZero = “”; if(偏移量%60<10) extraZero=“0”; console.log( “Your timezone is- GMT-” + Math.floor(offset/60)+“:”+extraZero+(offset%60)); }
将OffSet转换为正数:
var offset = new Date().getTimezoneOffset();
console.log(offset);
this.timeOffSet = offset + (-2*offset);
console.log(this.timeOffSet);