web-dev-qa-db-ja.com

ユーザーのタイムゾーンを検出する方法は?

IPまたはhttpヘッダーに基づいて、ユーザーが現在いるタイムゾーンを知る必要があります。

私はこの問題に関して多くの答えを得ましたが、それらの答えを理解できませんでした。ある人は-new Date().getTimezoneOffset()/60ここから )を使うと言った。しかし、それはどういう意味ですか?

(index.php)ページのルートにdate_default_timezone_set("Asia/Calcutta");があります。そのため、タイムゾーンを動的に取得し、Asia/Calcuttaの代わりに設定する必要があります。

26
Dan

コードに関する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(); //'Asia/Kolhata' for 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>
35

ブラウザのタイムゾーン情報はHTTP仕様の一部ではないため、ヘッダーから取得することはできません。

(たとえばモバイルデバイスのGPSから)位置座標がある場合は、タイムゾーンを見つけることができます これらの方法のいずれかを使用して 。ただし、IPは別のタイムゾーンにある可能性のあるISPまたはプロキシサーバーのIPであることが多いため、IPアドレスによるジオロケーションは優れたソリューションではありません。

jsTimeZoneDetect ライブラリを使用するなど、タイムゾーンの検出を試みるために使用できるいくつかの戦略があります。 moment.jsを使用している場合は、同じことを行うmoment.tz.guess()と呼ばれるmoment-timezoneに組み込み関数があります。

JavaScriptのgetTimezoneOffset()関数を使用するという考え方は、タイムゾーンを取得していないという点で欠陥があります。特定の日付の1つのオフセットだけです。 TimeZoneタグwiki の「TimeZone!= Offset」というタイトルのセクションを参照してください。

どのように見ても、最終的には次の2つのアプローチのいずれかを決定する必要があります。

OR

  • UTCでのみブラウザーに時間を送信し、ブラウザーでJavaScriptを使用して、ユーザーがコンピューターに設定しているローカルタイムゾーンに変換します。

これについては、C#の観点から この回答 で詳しく説明します。

23

依存関係:

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

引用: SIPでMaxMind GeoIPとPHP by Stanislav Khromov)で訪問者の現地時間、日の出と日没時間を取得します

2
davidcondrey

これはうまくいきます...

  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'));
0
Bernhard Lauber

タイムゾーンはHTTPヘッダーでは使用できませんが、国(略称)はACCEPT_LANGUAGEヘッダーにあります。 「en-US」のようなものになります(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時間、夏にDSTがアクティブで1時間追加されます)。 Cookieを使用して、これをPHPで使用できるようにします。 PHPこれに一致するゾーンと国をTZデータベースで検索します。ここ(米国、-6S1)には7つの一致するゾーンがあり、最初は "America/Chicago"です。

ところで、データベースには、DSTが1時間以外の何かを追加する2つのゾーンがあります。ロードハウアイランド(10.5W0.5)と南極のトロールステーション(0W2)です。

0
Mark Lloyd

1つの解決策は、彼らに尋ねることです!特に、ユーザーをキャプチャ/登録できるメンバーシステムでは、その時点でユーザーに選択肢を与えます。シンプルだが正確。

0
Antony