如何检测用户的时区?



我需要知道我的用户目前在什么时区基于他们的IP或http头。

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

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

用代码来总结Matt Johnson的回答:

<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>

浏览器的时区信息不是HTTP规范的一部分,所以你不能从标头中获取它。

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

您可以使用一些策略来尝试检测时区,例如使用jsTimeZoneDetect库,这是一个很好的起点,但是不够完美,您不能仅仅依赖于它。如果你使用的是moment.js,在moment-timezone中有一个内置的函数叫做moment.tz.guess(),它可以做同样的事情。

使用JavaScript的getTimezoneOffset()函数的想法是有缺陷的,因为你没有得到一个时区-只是一个特定日期的偏移量。请参阅TimeZone标签wiki的标题为"TimeZone != Offset"的部分。

无论你怎么看,最终你必须在两种方法中选择一种:

  • 要求用户告诉你他们的时区,从某种下拉列表或基于地图的时区选择器控件。

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

我将从c#的角度更详细地讨论这个问题。

依赖:

  1. http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
  2. http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
  3. //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

一个解决方案是问他们!特别是在会员系统中,你可以捕获/注册用户——在这一点上给他们一个选择。简单而准确。

这很好…

  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'));

时区在HTTP报头中不可用,但是国家(缩写)在ACCEPT_LANGUAGE报头中。它会像"en-US"(美国是国家代码)。可以将此信息与JavaScript信息结合使用,以便更好地了解用户的时区。

这是我在JS中使用的:

function timezone() {
  var now = new Date();
  var jano = new Date(now.getFullYear(), 0, 1).getTimezoneOffset()/-60;
  var julo = new Date(now.getFullYear(), 6, 1).getTimezoneOffset()/-60;
  var tz = Math.min(jano, julo);
  if (jano != julo) tz += ((jano < julo) ? 'S' : 'W') + Math.abs(jano - julo);
  return tz;
}

返回一个类似"-6S1"的字符串,表示中心区域(标准时间偏移为-6小时,夏令时在夏季有效并增加1小时)。我使用cookie使其对PHP可用。PHP在TZ数据库中搜索与之匹配的区域和国家。这里(US, -6S1)有7个匹配区域,第一个是"America/Chicago"。

顺便说一句,数据库中有两个区域的夏时制增加了1小时以外的时间:Lord Howe Island (10.5W0.5)和Troll Station, Antarctica (0W2)。

相关内容

  • 没有找到相关文章