web-dev-qa-db-fra.com

Comment obtenir un fuseau horaire via une adresse IP dans PHP

Je souhaite obtenir un fuseau horaire via une adresse IP en PHP. En fait, j'ai une application qui s'exécutera sur la machine cliente. J'ai l'adresse IP de la machine cliente. Mais je ne parviens pas à obtenir le fuseau horaire de chaque ordinateur client.

33
Devesh M

Obtenez une flotte de les camions vélos et conduite dans le monde entier, en notant l'adresse IP de chacun des routeurs sans fil et les coordonnées GPS actuelles.

C'est ce que Google a fait. Je ne plaisante pas. 

Mise à jour: Si vous ne pouvez vous le permettre, utilisez MaxMind GeoLite2 , qui vous indique le fuseau horaire par adresse IP. Il possède une API PHP locale (le "lecteur de base de données"). 

30
Neil McGuigan

On ne peut même pas compter sur l’adresse IP pour établir une correspondance avec un pays; vous marchez sur de la glace mince si vous souhaitez également obtenir un fuseau horaire. Il vaut mieux que le client vous envoie le fuseau horaire, éventuellement dans un en-tête.

Voir Tor: anonymat en ligne pour encore une autre raison de ne plus utiliser les adresses IP pour des choses pour lesquelles ils n'ont pas été conçus.

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

Parfois, cela ne fonctionnera pas sur le serveur local, alors essayez sur le serveur.

14
Chandrika Shah

Si vous l'exécutez sur la machine locale, vous pouvez vérifier le fuseau horaire configuré. 
http://www.php.net/manual/en/function.date-default-timezone-get.php

Il existe des méthodes bien meilleures et plus fiables que d'essayer de deviner le fuseau horaire à l'aide de GeoIP. Si vous avez de la chance, essayez: http://www.php.net/manual/fr/book.geoip.php

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

Il n'existe pas de moyen absolument certain d'obtenir le fuseau horaire du client, mais si le client soumet la date et l'heure à partir de sa machine, vous pouvez le calculer en fonction de l'heure qu'il est par rapport à GMT. Donc, s'il est 19 h 00 sur leur machine et qu'il est 12 h 00 GMT, vous pouvez alors déterminer qu'ils sont -5 à l'heure GMT ou (EST/DST)

10
cgp

Ce n’est pas une bonne idée de rechercher le fuseau horaire d’un utilisateur via son adresse IP, car il peut accéder à son compte depuis différents endroits à différentes heures. Il est donc impossible de localiser son fuseau horaire via l'adresse IP. Mais j'ai essayé de trouver une solution et je donne mon code ici. Toute critique sur la technique de codage sera très appréciée.

<?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';
}
7
masud_moni

Ce n'est pas simple, mais j'ai l'heure, y compris le décalage de l'heure d'été à partir de 2 appels api utilisant jquery et php. Tout cela pourrait être fait dans PHP assez facilement avec un peu d'adaptation . Je suis sûr que cela pourrait être présenté différemment aussi, mais je l'ai simplement extrait du code existant qui convenait à mes besoins à l'époque.

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

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

Inscrivez-vous pour une clé gratuite ici: http://ipinfodb.com/register.php (pas de limite, mais en file d'attente si plus d'une demande par seconde)

3
Andy Gee

Si ce que vous devez savoir, c'est le fuseau horaire des utilisateurs parcourant votre page Web, vous pouvez utiliser un service tel que IP2LOCATION pour deviner le fuseau horaire. N'oubliez pas cependant, comme l'a dit altCognito, que ce n'est pas une façon précise de dire le fuseau horaire du client. Il y a quelques problèmes de précision avec cette approche.

2
Pablo Santa Cruz

Consultez la base de données Maxmind GeoLite2. Il contient des détails sur le continent/pays/ville et lat/lon pour la plupart des adresses IP, y compris le time_zone comme vous pouvez le voir ci-dessous.

Je décris comment compiler l'extension PHP et comment utiliser les bases de données mmdb dans PHP ici:

Introduction à Maxmind GeoLite2 avec Kohana PHP

enter image description here

1
Jamie

Voici un exemple utilisant une API location qui mappe une adresse IP sur un fuseau horaire, par exemple. envoyer une demande à https://ipapi.co/<IP-Address>/timezone/ & récupérer le fuseau horaire pour cette adresse IP. 

Code PHP

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

L'exactitude n'est pas à 100% comme d'autres l'ont dit.

0
user