如何收集访问者的时区信息?

我两者都需要:

时区(例如,欧洲/伦敦) 与UTC或GMT的偏移(例如,UTC+01)


当前回答

这个值来自用户的机器,可以随时更改,所以我认为没关系,我只是想获得一个近似值,然后在我的服务器上将其转换为GMT。

例如,我来自台湾,它为我返回“+8”。

工作示例

JS

function timezone() {
    var offset = new Date().getTimezoneOffset();
    var minutes = Math.abs(offset);
    var hours = Math.floor(minutes / 60);
    var prefix = offset < 0 ? "+" : "-";
    return prefix+hours;
}


$('#result').html(timezone());

HTML

<div id="result"></div>

结果

+8

其他回答

我在我的项目中写了一个函数,它以hh:mm格式返回时区。我希望这能帮助到一些人:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}

// Outputs: +5:00

getTimeZone() { var offset = new Date().getTimezoneOffset(), o = Math.abs(offset); 返回(offset < 0 ?"+": "-") +("00" +数学。地板(o / 60)) .slice (2 ) + ":" + (" 00”+ (o % 60)) .slice (2); } //查看输出 document . write (getTimeZone ());

工作小提琴

带有注释的代码

/**
 * Get client side timezone.
 *
 * @returns {(+|-)HH:mm} - Where `HH` is 2 digits hours and `mm` 2 digits minutes.
 * @example
 * // From Indian/Reunion with UTC+4
 * // '+04:00'
 * getTimeZone()
 */
const getTimeZone = () => {
  const timezoneOffset = new Date().getTimezoneOffset()
  const offset = Math.abs(timezoneOffset)
  const offsetOperator = timezoneOffset < 0 ? '+' : '-'
  const offsetHours = Math.floor(offset / 60).toString().padStart(2, '0')
  const offsetMinutes = Math.floor(offset % 60).toString().padStart(2, '0')

  return `${offsetOperator}${offsetHours}:${offsetMinutes}`
}

一旦我有了这个“简单”的任务,我使用(new Date()). gettimezoneoffset() -这里广泛建议的方法。但事实证明,这个解决方案并不完全正确。 在我的例子中,由于一些未记录的原因,new Date()返回GMT+0200,而new Date(0)返回GMT+0300,这是正确的。从那时起我就一直用

(new Date(0)). gettimezoneoffset()来获得正确的时间差。

为什么不直接使用:

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和本地时间之间的差值(以分钟为单位)。

这可能不是最优雅的解决方案,但却是最通用的。

这使用了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中明显没有,尽管它正在进行中