Html 确定用户的时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 22:05:47  来源:igfitidea点击:

Determine a user's timezone

htmlbrowsertimezoneuser-agenttimezone-offset

提问by Kevin Dente

Is there a standard way for a web server to be able to determine a user's timezone within a web page?

Web 服务器是否有一种标准方法可以确定网页中用户的时区?

Perhaps from an HTTP header or part of the user-agentstring?

也许来自 HTTP 标头或user-agent字符串的一部分?

回答by JD Isaacks

-new Date().getTimezoneOffset()/60;

The method getTimezoneOffset()will subtract your time from GMT and return the number of minutes. So if you live in GMT-8, it will return 480.

该方法getTimezoneOffset()将从 GMT 中减去您的时间并返回分钟数。所以如果你住在 GMT-8,它会返回 480。

To put this into hours, divide by 60. Also, notice that the sign is the opposite of what you need - it's calculating GMT's offset from your time zone, not your time zone's offset from GMT. To fix this, simply multiply by -1.

要将其转换为小时,请除以 60。另外,请注意该符号与您需要的符号相反 - 它正在计算 GMT 与您的时区的偏移量,而不是您的时区与 GMT 的偏移量。要解决这个问题,只需乘以 -1。

Also note that w3schoolsays:

还要注意w3school说:

The returned value is not a constant, because of the practice of using Daylight Saving Time.

由于使用夏令时的做法,返回值不是常量。

回答by Ishmaeel

The most popular (==standard?) way of determining the time zone I've seen around is simply asking the users themselves.If your website requires subscription, this could be saved in the users' profile data. For anon users, the dates could be displayed as UTC or GMT or some such.

我见过的最流行的(==标准?)确定时区的方法就是简单地询问用户自己。如果您的网站需要订阅,这可以保存在用户的个人资料数据中。对于匿名用户,日期可以显示为 UTC 或 GMT 等。

I'm not trying to be a smart aleck. It's just that sometimes some problems have finer solutions outside of any programming context.

我不是想成为一个聪明的人。只是有时某些问题在任何编程上下文之外都有更好的解决方案。

回答by Mads Kristiansen

There are no HTTP headers that will report the clients timezone so far although it has been suggested to include it in the HTTP specification.

到目前为止,还没有 HTTP 标头会报告客户端时区,尽管有人建议将其包含在 HTTP 规范中。

If it was me, I would probably try to fetch the timezone using clientside JavaScript and then submit it to the server using Ajax or something.

如果是我,我可能会尝试使用客户端 JavaScript 获取时区,然后使用 Ajax 或其他方式将其提交到服务器。

回答by pix0r

JavaScript is the easiest way to get the client's local time. I would suggest using an XMLHttpRequestto send back the local time, and if that fails, fall back to the timezone detected based on their IP address.

JavaScript 是获取客户端本地时间的最简单方法。我建议使用XMLHttpRequest发回本地时间,如果失败,则退回到根据其 IP 地址检测到的时区。

As far as geolocation, I've used MaxMind GeoIPon several projects and it works well, though I'm not sure if they provide timezone data. It's a service you pay for and they provide monthly updates to your database. They provide wrappers in several web languages.

至于地理定位,我已经在几个项目中使用了MaxMind GeoIP,它运行良好,但我不确定它们是否提供时区数据。这是一项您付费的服务,他们每月为您的数据库提供更新。他们提供多种网络语言的包装器。

回答by Matt Johnson-Pint

First, understand that time zone detection in JavaScript is imperfect. You can get the local time zone offsetfor a particular date and time using getTimezoneOffseton an instance of the Dateobject, but that's not quite the same as a full IANA time zonelike America/Los_Angeles.

首先,了解 JavaScript 中的时区检测是不完美的。您可以使用对象实例获取特定日期和时间的本地时区偏移量,但这与完整的IANA 时区(如.getTimezoneOffsetDateAmerica/Los_Angeles

There are some options that can work though:

有一些选项可以工作:

const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tzid);

The result is a string containing the IANA time zone setting of the computer where the code is running.

结果是一个字符串,其中包含运行代码的计算机的 IANA 时区设置。

Supported environments are listed in the Intl compatibility table. Expand the DateTimeFormatsection, and look at the feature named resolvedOptions().timeZone defaults to the host environment.

支持的环境在国际兼容性表中列出。展开该DateTimeFormat部分,然后查看名为 的功能resolvedOptions().timeZone defaults to the host environment

  • Some libraries, such as Luxonuse this API to determine the time zone through functions like luxon.Settings.defaultZoneName.

    • If you need to support an wider set of environments, such as older web browsers, you can use a library to make an educated guessat the time zone. They work by first trying the IntlAPI if it's available, and when it's not available, they interrogate the getTimezoneOffsetfunction of the Dateobject, for several different points in time, using the results to choose an appropriate time zone from an internal data set.

    Both jsTimezoneDetectand moment-timezonehave this functionality.

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();
    

    In both cases, the result can only be thought of as a guess. The guess may be correct in many cases, but not all of them.

    Additionally, these libraries have to be periodically updated to counteract the fact that many older JavaScript implementations are only aware of the currentdaylight saving time rule for their local time zone. More details on that here.

  • 一些库(例如Luxon)使用此 API 通过诸如luxon.Settings.defaultZoneName.

    • 如果您需要支持更广泛的环境,例如较旧的 Web 浏览器,您可以使用库对时区进行有根据的猜测Intl如果 API 可用,它们首先尝试API,当 API 不可用时,它们会询问对象的getTimezoneOffset功能Date,针对几个不同的时间点,使用结果从内部数据集中选择合适的时区。

    无论jsTimezoneDetect时刻,时区具有此功能。

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();
    

    在这两种情况下,结果只能被认为是一种猜测。在许多情况下,猜测可能是正确的,但不是所有情况。

    此外,这些库必须定期更新,以抵消许多较旧的 JavaScript 实现只知道其本地时区的当前夏令时规则的事实。 更多细节在这里。

Ultimately, a better approach is to actually ask your user for their time zone. Provide a setting that they can change. You can use one of the above options to choose a defaultsetting, but don't make it impossible to deviate from that in your app.

最终,更好的方法是实际询问您的用户他们的时区。提供他们可以更改的设置。您可以使用上述选项之一来选择默认设置,但不要在您的应用中偏离默认设置。

There's also the entirely different approach of notrelying on the time zone setting of the user's computer at all. Instead, if you can gather latitude and longitude coordinates, you can resolve those to a time zone using one of these methods. This works well on mobile devices.

还有一种完全不同的方法,即完全依赖于用户计算机的时区设置。相反,如果您可以收集纬度和经度坐标,则可以使用以下方法之一将它们解析为时区。这在移动设备上运行良好。

回答by Adam

Here is a robust JavaScript solution to determine the time zone the browser is in.

这是一个强大的 JavaScript 解决方案,用于确定浏览器所在的时区。

>>> var timezone = jstz.determine();
>>> timezone.name(); 
"Europe/London"

https://bitbucket.org/pellepim/jstimezonedetect

https://bitbucket.org/pelepim/jstimezonedetect

Appendix 1: Now this project is located on GitHub: https://github.com/pellepim/jstimezonedetect

附录1:现在这个项目位于GitHub上:https: //github.com/pellepim/jstimezonedetect

回答by Joseph Lust

Here is a more complete way.

这是一个更完整的方法。

  1. Get the timezone offset for the user
  2. Test some days on daylight saving boundaries to determine if they are in a zone that uses daylight saving.
  1. 获取用户的时区偏移量
  2. 在夏令时边界上测试几天以确定它们是否在使用夏令时的区域中。

An excerpt is below:

摘录如下:

function TimezoneDetect(){
    var dtDate = new Date('1/1/' + (new Date()).getUTCFullYear());
    var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
    var intMonth;
    var intHoursUtc;
    var intHours;
    var intDaysMultiplyBy;

    // Go through each month to find the lowest offset to account for DST
    for (intMonth=0;intMonth < 12;intMonth++){
        //go to the next month
        dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);

        // To ignore daylight saving time look for the lowest offset.
        // Since, during DST, the clock moves forward, it'll be a bigger number.
        if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
            intOffset = (dtDate.getTimezoneOffset() * (-1));
        }
    }

    return intOffset;
}

Getting TZ and DST from JS(via Way Back Machine)

从 JS 获取 TZ 和 DST(通过 Way Back Machine)

回答by Westy92

Using Unkwntech's approach, I wrote a function using jQuery and PHP. This is tested and does work!

使用 Unkwntech 的方法,我使用 jQuery 和 PHP 编写了一个函数。这是经过测试的,确实有效!

On the PHP page where you want to have the timezone as a variable, have this snippet of code somewhere near the top of the page:

在您希望将时区作为变量的 PHP 页面上,将这段代码放在页面顶部附近的某处:

<?php
    session_start();
    $timezone = $_SESSION['time'];
?>

This will read the session variable "time", which we are now about to create.

这将读取我们现在将要创建的会话变量“time”。

On the same page, in the <head>, you need to first of all include jQuery:

在同一页面上,在 <head> 中,您首先需要包含 jQuery:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

Also in the <head>, below the jQuery, paste this:

同样在 <head> 中,在 jQuery 下方,粘贴以下内容:

<script type="text/javascript">
    $(document).ready(function() {
        if("<?php echo $timezone; ?>".length==0){
            var visitortime = new Date();
            var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
            $.ajax({
                type: "GET",
                url: "http://example.org/timezone.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

You may or may not have noticed, but you need to change the URL to your actual domain.

您可能注意到也可能没有注意到,但您需要将 URL 更改为您的实际域。

One last thing. You are probably wondering what the heck timezone.php is. Well, it is simply this: (create a new file called timezone.phpand point to it with the above URL)

最后一件事。您可能想知道 timezone.php 到底是什么。嗯,就是这样:(创建一个名为timezone.php的新文件,并用上面的 URL 指向它)

<?php
    session_start();
    $_SESSION['time'] = $_GET['time'];
?>

If this works correctly, it will first load the page, execute the JavaScript, and reload the page. You will then be able to read the $timezone variable and use it to your pleasure! It returns the current UTC/GMT time zone offset (GMT -7) or whatever timezone you are in.

如果这工作正常,它将首先加载页面,执行 JavaScript,然后重新加载页面。然后,您将能够读取 $timezone 变量并随意使用它!它返回当前的 UTC/GMT 时区偏移量 (GMT -7) 或您所在的任何时区。

回答by philfreo

To submit the timezone offset as an HTTP header on AJAX requests with jQuery

使用jQuery在 AJAX 请求上将时区偏移量作为 HTTP 标头提交

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
    }
});

You can also do something similar to get the actual time zone name by using moment.tz.guess();from http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

您也可以通过做同样获得实际的时区名称的东西moment.tz.guess();http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

回答by Keyo

I still have not seen a detailed answer here that gets the time zone. You shouldn't need to geocode by IP address or use PHP (lol) or incorrectly guess from an offset.

我仍然没有在这里看到获取时区的详细答案。您不应该需要按 IP 地址进行地理编码或使用 PHP (lol) 或从偏移量中错误地猜测。

Firstly a time zone is not just an offset from GMT. It is an area of land in which the time rules are set by local standards. Some countries have daylight savings, and will switch on DST at differing times. It's usually important to get the actual zone, not just the current offset.

首先,时区不仅仅是格林威治标准时间的偏移量。这是一个时间规则由当地标准制定的土地区域。一些国家/地区实行夏令时,会在不同时间开启 DST。获取实际区域通常很重要,而不仅仅是当前的偏移量。

If you intend to store this timezone, for instance in user preferences you want the zone and not just the offset. For realtime conversions it won't matter much.

如果您打算存储此时区,例如在用户首选项中,您需要时区而不仅仅是偏移量。对于实时转换,它不会有太大关系。

Now, to get the time zone with javascript you can use this:

现在,要使用 javascript 获取时区,您可以使用以下命令:

>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.

However I found it easier to simply use this robust plugin which returns the Olsen formatted timezone:

但是我发现简单地使用这个强大的插件会更容易,它返回奥尔森格式的时区:

https://github.com/scottwater/jquery.detect_timezone

https://github.com/scottwater/jquery.detect_timezone