Como obter fuso horário através do endereço IP em PHP

Eu quero obter fuso horário através de um endereço IP em PHP. Na verdade, eu tenho um aplicativo que será executado na máquina cliente. Eu tenho o endereço IP da máquina cliente. Mas não consigo obter o fuso horário para cada máquina cliente.

    Obtenha uma frota de caminhões de bicicleta e dirija ao redor do mundo registrando o endereço IP do roteador sem fio de todos e a coordenada GPS atual.

    Foi o que o Google fez. Eu não estou brincando.

    Atualização: se você não pode pagar isso, use o MaxMind GeoLite2 , que informa o fuso horário pelo endereço IP. Tem uma API PHP local (o “leitor de database”).

    O endereço de IP não pode ser invocado para mapear para um país; você está pisando em gelo fino se você também deseja obter fuso horário. Você está melhor para que o cliente lhe envie o fuso horário, talvez em um header.

    Veja Tor: anonimato online por mais uma razão para parar de usar endereços IP para coisas pelas quais eles não foram projetados.

    Não há uma maneira absolutamente certa de obter o fuso horário do cliente, mas se você tiver o cliente enviar a data e a hora da sua máquina, você pode calculá-lo com base no tempo que é relativo ao GMT. Então, se são 7:00 da tarde na sua máquina e são as 12:00 da manhã GMT, então você pode determinar que eles são -5 de GMT ou (EST / DST)

    Se você estiver executando na máquina local, você pode verificar o fuso horário configurado.
    http://www.php.net/manual/en/function.date-default-timezone-get.php

    Há methods muito melhores e mais confiáveis, tentando adivinhar o fuso horário usando o GeoIP. Se você está com sorte, tente: 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']); 

    Não é uma boa idéia procurar o fuso horário de um usuário através do endereço IP dele, pois ele pode acessar sua conta de diferentes lugares em horários diferentes. Portanto, é impossível localizar seu fuso horário através do endereço IP. Mas tentei encontrar uma solução e estou dando o meu código aqui. Qualquer crítica sobre a técnica de codificação será muito apreciada.

     < ?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 '
    '.$timezone_id.' '.$distance; if (!$time_zone || $tz_distance > $distance) { $time_zone = $timezone_id; $tz_distance = $distance; } } } return $time_zone; } return 'unknown'; }

    Não é direto, mas eu recebo o tempo, incluindo compensação de verão, de 2 chamadas api usando jquery e php. Tudo isso pode ser feito em PHP facilmente com um pouco de adaptação. Tenho certeza de que isso poderia ser descrito de forma diferente também, mas eu apenas o peguei do código existente que correspondiam às minhas necessidades no momento.

    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"}'; } 

    Registre-se para uma chave gratuita aqui: http://ipinfodb.com/register.php (sem limites, mas em fila, se houver mais de 1 pedido por segundo)

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

    Algumas vezes, não funcionará no servidor local, então tente no servidor.

    Se o que você precisa saber é o fuso horário dos usuários que navegam na sua página, você pode usar algum serviço como IP2LOCATION para adivinhar o fuso horário. Tenha em mente, porém, como disse a altCognito, esta não é uma maneira 100% precisa de informar o fuso horário do cliente. Existem alguns problemas de precisão com essa abordagem.

    Confira o database Maxmind GeoLite2. Ele contém detalhes sobre o continente / país / cidade e lat / lon para a maioria dos endereços IP, incluindo o time_zone como você pode ver abaixo.

    Eu descrevo como compilar a extensão PHP e como usar os bancos de dados mmdb em PHP aqui:

    Introdução ao Maxmind GeoLite2 com o Kohana PHP

    insira a descrição da imagem aqui

    Aqui está um exemplo usando uma API de localização que mapeia o endereço IP para o fuso horário, por exemplo, envie uma solicitação para https://ipapi.co//timezone/ & get back timezone para esse endereço IP.

    Código PHP

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

    A precisão não é 100%, como outros disseram.