2009-04-13 3 views
29

Я хочу получить часовой пояс через IP-адрес в PHP. На самом деле, у меня есть приложение, которое будет запускаться на клиентской машине. У меня есть IP-адрес клиентской машины. Но я не могу получить часовой пояс для каждой клиентской машины.Как получить часовой пояс через IP-адрес в PHP

ответ

9

Если вы используете его на локальном компьютере, вы можете проверить настроенный часовой пояс.
http://www.php.net/manual/en/function.date-default-timezone-get.php

Есть много лучших и надежных методов, которые пытаются угадать часовой пояс с помощью GeoIP. Если вы чувствуете себя счастливыми, попробуйте: http://www.php.net/manual/en/book.geoip.php

$region = geoip_region_by_name('www.example.com'); 
$tz = geoip_time_zone_by_country_and_region($region['country_code'], 
              $region['region']); 
+0

Приложение работает на локальной машине, но я хочу получить часовой пояс через IP на стороне сервера, а не на локальной машине. –

+0

Я бы хотел, чтобы локальная копия данных о часовых поясах GeoIP. – Jacco

10

Там нет абсолютно верного способа получить временную зону клиента, но если у вас есть клиент представить дату и время от их машины, вы можете вычислить его на основе того, что время относительно GMT. Итак, если это 7:00 вечера на их машине, и это 12:00 часов по Гринвичу, то вы можете определить, что они равны -5 от GMT или (EST/DST)

+6

Временные интервалы довольно сложны, так как большинство проблем интернационализации. Если вы знаете свое текущее время И если они находятся на летнем или нет, то вы можете определить их часовой пояс. Однако выяснение дневного света очень сложно (опять же) – Jacco

+3

Это отличная идея в теории, пока вы не включите DST. Который заставляет меня хотеть плакать. – dudewad

+0

Это отличная идея. И DST не имеет никакого значения, поскольку мы всегда сохраняем GMT на сервере в любом случае :) – frodeborli

14

IP-адрес нельзя полагаться только на карту страна; вы наступаете на тонкий лед, если хотите получить часовой пояс. Вам лучше, если клиент отправит вам часовой пояс, возможно, в заголовке.

См. Tor: anonymity online еще одна причина, чтобы прекратить использование IP-адресов для вещей, для которых они не предназначены.

+12

Часто, хотя вы можете предоставить пользователю «наилучшие предположения» автоматически заполненные поля формы, и в этом случае нет ничего плохого в этом. –

+0

Ничего плохого в чем? –

+4

Ничего плохого в использовании ip для приближения к часовому поясу. – unflores

2

Если вам нужно знать часовой пояс пользователей, просматривающих вашу веб-страницу, то вы можете использовать некоторую услугу, например IP2LOCATION, чтобы угадать часовой пояс. Имейте в виду, хотя, как сказал altCognito, это не 100% точный способ сообщить часовому поясу клиента. С этим подходом возникают некоторые проблемы с точностью.

25

Получить автопарк грузовиков велосипеды и проехать по всему миру, регистрируя IP-адрес беспроводного маршрутизатора и текущую координату GPS.

Это то, что сделал Google. Я не шучу.

Обновление: Если вы не можете позволить себе это, используйте MaxMind GeoLite2, в котором указывается часовой пояс по IP-адресу. Он имеет локальный PHP API («читатель базы данных»).

+9

Это практический ответ на этот вопрос? – footy

+10

зависит от вашей компании, я думаю :) –

+0

Источник? Я нахожу это действительно интересным. – andychase

3

Это не прямой, но я получаю время, в том числе смещение на летнее время, из 2 вызовов api с использованием jquery и php. Все это можно было бы сделать на PHP довольно легко с некоторой адаптацией. Я уверен, что это тоже можно было бы разложить, но я просто взял его из существующего кода, который соответствовал моим потребностям в то время.

Jquery/PHP:

function get_user_time(){ 
    var server_time = <? echo time(); ?>; //accuracy is not important it's just to let google know the time of year for daylight savings time 
    $.ajax({ 
     url: "locate.php", 
     dataType: "json", 
     success: function(user_location) { 
      if(user_location.statusCode=="OK"){ 
       $.ajax({ 
        url: "https://maps.googleapis.com/maps/api/timezone/json?location="+user_location.latitude+","+user_location.longitude+"&timestamp="+server_time+"&sensor=false", 
        dataType: "json", 
        success: function(user_time) { 
         if(user_time.statusCode=="error"){ 
          //handle error 
         }else{ 
          user_time.rawOffset /= 3600; 
          user_time.dstOffset /= 3600; 
          user_real_offset = user_time.rawOffset+user_time.dstOffset+user_time.utc; 
          //do something with user_real_offset 
         } 
        } 
       }); 
      } 
     } 
    }); 
} 

locate.php

function get_client_ip() { 
    $ipaddress = ''; 
    if ($_SERVER['HTTP_CLIENT_IP']) 
     $ipaddress = $_SERVER['HTTP_CLIENT_IP']; 
    else if($_SERVER['HTTP_X_FORWARDED_FOR']) 
     $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    else if($_SERVER['HTTP_X_FORWARDED']) 
     $ipaddress = $_SERVER['HTTP_X_FORWARDED']; 
    else if($_SERVER['HTTP_FORWARDED_FOR']) 
     $ipaddress = $_SERVER['HTTP_FORWARDED_FOR']; 
    else if($_SERVER['HTTP_FORWARDED']) 
     $ipaddress = $_SERVER['HTTP_FORWARDED']; 
    else if($_SERVER['REMOTE_ADDR']) 
     $ipaddress = $_SERVER['REMOTE_ADDR']; 
    else 
     $ipaddress = 'UNKNOWN'; 

    return $ipaddress; 
} 
$location = file_get_contents('http://api.ipinfodb.com/v3/ip-city/?key=xxxxxxxxx&ip='.get_client_ip().'&format=json'); 
$location = json_decode($location,true); 
if(is_array($location)){ 
    date_default_timezone_set('UTC'); 
    $location['utc'] = time(); 
    echo json_encode($location); 
}else{ 
    echo '{"statusCode":"error"}'; 
} 

Регистрация для бесплатного ключа здесь: http://ipinfodb.com/register.php (без каких-либо ограничений, но в очереди, если более чем один запрос в секунду)

1

Ознакомьтесь с базой данных Maxmind GeoLite2. Он содержит сведения о континенте/стране/городе и lat/lon для большинства IP-адресов, включая time_zone, как вы можете видеть ниже.

я описываю, как скомпилировать расширение PHP, и как использовать базы данных MMDB в PHP здесь:

Intro to Maxmind GeoLite2 with Kohana PHP

enter image description here

6

Это не очень хорошая идея для поиска часовой пояс через его или ее адрес ip, поскольку он может получить доступ к своей учетной записи из разных мест в разное время. Таким образом, невозможно определить его часовой пояс через ip-адрес. Но я попытался найти решение, и я даю свой код здесь. Любая критика в отношении техники кодирования будет высоко оценена.

<?php 

$time_zone = getTimeZoneFromIpAddress(); 
echo 'Your Time Zone is '.$time_zone; 

function getTimeZoneFromIpAddress(){ 
    $clientsIpAddress = get_client_ip(); 

    $clientInformation = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$clientsIpAddress)); 

    $clientsLatitude = $clientInformation['geoplugin_latitude']; 
    $clientsLongitude = $clientInformation['geoplugin_longitude']; 
    $clientsCountryCode = $clientInformation['geoplugin_countryCode']; 

    $timeZone = get_nearest_timezone($clientsLatitude, $clientsLongitude, $clientsCountryCode) ; 

    return $timeZone; 

} 

function get_client_ip() { 
    $ipaddress = ''; 
    if (getenv('HTTP_CLIENT_IP')) 
     $ipaddress = getenv('HTTP_CLIENT_IP'); 
    else if(getenv('HTTP_X_FORWARDED_FOR')) 
     $ipaddress = getenv('HTTP_X_FORWARDED_FOR'); 
    else if(getenv('HTTP_X_FORWARDED')) 
     $ipaddress = getenv('HTTP_X_FORWARDED'); 
    else if(getenv('HTTP_FORWARDED_FOR')) 
     $ipaddress = getenv('HTTP_FORWARDED_FOR'); 
    else if(getenv('HTTP_FORWARDED')) 
     $ipaddress = getenv('HTTP_FORWARDED'); 
    else if(getenv('REMOTE_ADDR')) 
     $ipaddress = getenv('REMOTE_ADDR'); 
    else 
     $ipaddress = 'UNKNOWN'; 
    return $ipaddress; 
} 

function get_nearest_timezone($cur_lat, $cur_long, $country_code = '') { 
    $timezone_ids = ($country_code) ? DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_code) 
     : DateTimeZone::listIdentifiers(); 

    if($timezone_ids && is_array($timezone_ids) && isset($timezone_ids[0])) { 

     $time_zone = ''; 
     $tz_distance = 0; 

     //only one identifier? 
     if (count($timezone_ids) == 1) { 
      $time_zone = $timezone_ids[0]; 
     } else { 

      foreach($timezone_ids as $timezone_id) { 
       $timezone = new DateTimeZone($timezone_id); 
       $location = $timezone->getLocation(); 
       $tz_lat = $location['latitude']; 
       $tz_long = $location['longitude']; 

       $theta = $cur_long - $tz_long; 
       $distance = (sin(deg2rad($cur_lat)) * sin(deg2rad($tz_lat))) 
        + (cos(deg2rad($cur_lat)) * cos(deg2rad($tz_lat)) * cos(deg2rad($theta))); 
       $distance = acos($distance); 
       $distance = abs(rad2deg($distance)); 
       // echo '<br />'.$timezone_id.' '.$distance; 

       if (!$time_zone || $tz_distance > $distance) { 
        $time_zone = $timezone_id; 
        $tz_distance = $distance; 
       } 

      } 
     } 
     return $time_zone; 
    } 
    return 'unknown'; 
} 
0

Вот пример использования location API, который отображает IP-адрес для временной зоны, например, отправьте запрос на https://ipapi.co/<IP-Address>/timezone/ &, чтобы вернуть часовой пояс для этого IP-адреса.

PHP код

file_get_contents('https://ipapi.co/1.2.3.4/timezone/'); 

Точность не 100%, как говорили другие.

4
$ip = "189.240.194.147"; //$_SERVER['REMOTE_ADDR'] 
$ipInfo = file_get_contents('http://ip-api.com/json/' . $ip); 
$ipInfo = json_decode($ipInfo); 
$timezone = $ipInfo->timezone; 
date_default_timezone_set($timezone); 
echo date_default_timezone_get(); 
echo date('Y/m/d H:i:s'); 

Когда-нибудь он не будет работать на локальном сервере, поэтому попробуйте на сервере.

+0

очень полезно сэкономил много времени для меня –