Как получить часовой пояс через IP-адрес в PHP

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

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

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

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

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

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

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

Если вы используете его на локальном компьютере, вы можете проверить настроенный часовой пояс.
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']); 

Это не очень хорошая идея для поиска часового пояса пользователя через его или ее адрес 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'; } 

Это не прямо, но я получаю время, включая смещение на летнее время, из 2-х апи-вызовов, используя 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 запроса в секунду)

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

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

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

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

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

Введение в Maxmind GeoLite2 с Kohana PHP

введите описание изображения здесь

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

PHP-код

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

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