如何检测用户的时区?

IT技术 javascript php timezone
2021-02-04 14:34:08

我需要根据他们的 IP 或 http 标头知道我的用户当前所在的时区。

我得到了很多关于这个问题的答案,但我无法理解这些答案。有人说使用-new Date().getTimezoneOffset()/60从这里)。但是这是什么意思?

date_default_timezone_set("Asia/Calcutta");我的 (index.php) 页面的根目录中有一个因此,为此我必须动态获取时区并将其设置为Asia/Calcutta.

6个回答

总结马特约翰逊在代码方面的回答:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.min.js">
</script>
<script type="text/javascript">
  $(document).ready(function(){
    var tz = jstz.determine(); // Determines the time zone of the browser client
    var timezone = tz.name(); //For e.g.:"Asia/Kolkata" for the Indian Time.
    $.post("url-to-function-that-handles-time-zone", {tz: timezone}, function(data) {
       //Preocess the timezone in the controller function and get
       //the confirmation value here. On success, refresh the page.
     });
  });
</script>
@kjdion84 是的,但浏览器支持有限。如果您想支持较旧的浏览器版本,最好安装 polyfill。
2021-03-14 14:34:08
@FernandoTorres 我知道这就像 8yrs 旧代码,但它仍然有效:jsfiddle.net/elavarasanlee/2Le0uvp3/2你能详细说明什么对你不起作用吗?
2021-03-18 14:34:08
$.post("url-to-function-that-handles-time-zone", {tz: timezone}, function(data) { //在控制器函数中对时区进行预处理并得到 //这里的确认值。on成功,刷新页面。}); 我不明白这一行,你能解释一下吗?
2021-03-28 14:34:08
@Vijaykarthik:Ajax 调用会将动态获取的时区发送到控制器方法(因为开发人员正在使用 Codeigniter - MVC 框架)。在控制器方法中,他将设置时区 uisng date_default_timezone_set(timezone),如果时区无效,则返回 false!使用这个重新运行值,他必须决定是否刷新页面!
2021-04-08 14:34:08
您可以使用 vanilla javascriptIntl.DateTimeFormat().resolvedOptions().timeZone而不是整个库。
2021-04-10 14:34:08

浏览器的时区信息不是 HTTP 规范的一部分,因此您不能仅从标头中获取它。

如果您有位置坐标(例如来自移动设备 GPS),那么您可以使用以下方法之一找到时区然而,通过 IP 地址进行地理定位并不是一个很好的解决方案,因为 IP 通常是 ISP 或代理服务器的 IP,它们可能位于另一个时区。

您可以使用一些策略来尝试检测时区,例如使用jsTimeZoneDetect库,这是一个很好的起点,但不够完善,您不能仅依靠它。如果您使用的是 moment.js,则在 moment-timezone 中有一个内置函数moment.tz.guess()可以执行相同的操作。

使用 JavaScriptgetTimezoneOffset()函数的想法有缺陷,因为您没有获得时区 - 只是特定日期的单个偏移量。请参阅TimeZone 标签 wiki的标题为“TimeZone != Offset”的部分。

不管你怎么看,最终你必须决定两种方法之一:

或者

  • 仅以 UTC 时间向浏览器发送时间,并在浏览器上使用 JavaScript 转换为用户可能将其计算机设置为的任何本地时区。

我在这个答案中更详细地讨论了这个问题(从 ac# 的角度)

我喜欢第一种方法,因为让用户选择他正在使用的内容。从我的角度来看,依靠检测只是令人头疼,因为用户可能会不小心更改时间。
2021-03-11 14:34:08
很好的解释。我想使用第二种方法。但我是编程初学者。如何以 UTC 时间向浏览器发送时间,并在浏览器上使用 JavaScript 转换为任何本地时间?
2021-03-16 14:34:08
第二种解决方案使大多数 Web 应用程序走得很远,但在向用户发送有关带有时间戳的事件的电子邮件时,它会崩溃。服务器在 UTC 上运行,因此我们不会自动调整用户的时区。看起来解决方案是在登录时自动检测时区值并发送到服务器以存储在用户身上。然后我们可以使用该时区来调整我们发送的电子邮件。可能应该包括一个输入来控制帐户设置,只是为了更好的衡量。
2021-03-17 14:34:08
@Ashutosh - 您将在现有帖子中找到每个单独问题的答案。
2021-03-29 14:34:08
2021-04-09 14:34:08

依赖项:

  1. http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
  2. http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

    //Get remote IP
    $ip = $_SERVER['REMOTE_ADDR'];
    
    //Open GeoIP database and query our IP
    $gi = geoip_open("GeoLiteCity.dat", GEOIP_STANDARD);
    $record = geoip_record_by_addr($gi, $ip);
    
    //If we for some reason didnt find data about the IP, default to a preset location.
    if(!isset($record)) {
        $record = new geoiprecord();
        $record->latitude = 59.2;
        $record->longitude = 17.8167;
        $record->country_code = 'SE';
        $record->region = 26;
    }
    
    //Calculate the timezone and local time
    try {
        //Create timezone
        $user_timezone = new DateTimeZone(get_time_zone($record->country_code, ($record->region!='') ? $record->region : 0));
    
        //Create local time
        $user_localtime = new DateTime("now", $user_timezone);
        $user_timezone_offset = $user_localtime->getOffset();        
    }
    //Timezone and/or local time detection failed
    catch(Exception $e) {
        $user_timezone_offset = 7200;
        $user_localtime = new DateTime("now");
    }
    
    echo 'User local time: ' . $user_localtime->format('H:i:s') . '<br/>';
    echo 'Timezone GMT offset: ' . $user_timezone_offset . '<br/>';
    

引文:SGet 访问者本地时间、日出和日落时间通过 IP 与 MaxMind GeoIP 和 PHP 由 Stanislav Khromov

我认为最好的算法是根据地理 IP 位置结合用户代理时间偏移来选择时区。使用 geo-ip location 选择可能的时区列表(按检测到的位置和时区“home”位置之间的 geo-ip 距离排序)并选择接近用户代理时间偏移的第一个匹配项。
2021-03-14 14:34:08

一种解决方法是问他们!特别是在您可以捕获/注册用户的会员系统上 - 给他们一个选择。简单但准确。

这工作正常...

  echo <<<EOE
   <script type="text/javascript">
     if (navigator.cookieEnabled)
       document.cookie = "tzo="+ (- new Date().getTimezoneOffset());
   </script>
EOE;
  if (!isset($_COOKIE['tzo'])) {
    echo <<<EOE
      <script type="text/javascript">
        if (navigator.cookieEnabled) document.reload();
        else alert("Cookies must be enabled!");
      </script>
EOE;
    die();
  }
  $ts = new DateTime('now', new DateTimeZone('GMT'));
  $ts->add(DateInterval::createFromDateString($_COOKIE['tzo'].' minutes'));