Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中通过IP地址获取时区_Php_Time_Timezone_Ip - Fatal编程技术网

如何在PHP中通过IP地址获取时区

如何在PHP中通过IP地址获取时区,php,time,timezone,ip,Php,Time,Timezone,Ip,我想通过PHP中的IP地址获取时区。实际上,我有一个应用程序将在客户机上运行。我有客户端计算机的IP地址。但是我无法获取每个客户端计算机的时区。如果您在本地计算机上运行它,可以检查配置的时区 有很多更好、更可靠的方法,可以尝试使用GeoIP猜测时区。如果您感到幸运,请尝试: 没有绝对确定的方法来获取客户机的时区,但是如果您让客户机从他们的机器提交日期和时间,您可以根据它相对于GMT的时间来计算。因此,如果他们的机器上的时间是晚上7:00,格林尼治标准时间是凌晨12:00,那么您可以从格林尼治标

我想通过PHP中的IP地址获取时区。实际上,我有一个应用程序将在客户机上运行。我有客户端计算机的IP地址。但是我无法获取每个客户端计算机的时区。

如果您在本地计算机上运行它,可以检查配置的时区

有很多更好、更可靠的方法,可以尝试使用GeoIP猜测时区。如果您感到幸运,请尝试:


没有绝对确定的方法来获取客户机的时区,但是如果您让客户机从他们的机器提交日期和时间,您可以根据它相对于GMT的时间来计算。因此,如果他们的机器上的时间是晚上7:00,格林尼治标准时间是凌晨12:00,那么您可以从格林尼治标准时间或(EST/DST)确定它们是-5IP地址甚至不能用来映射到一个国家;如果你也想获得时区,那你就如履薄冰了。您最好让客户机向您发送时区,可能是在标题中


请参阅,了解停止使用IP地址的另一个原因。

如果您需要知道浏览您网页的用户的时区,那么您可以使用一些服务来猜测时区。但请记住,正如altCognito所说,这并不是一种100%准确地告知客户时区的方法。这种方法存在一些准确性问题。

这不是直截了当的,但我从使用jquery和php的两个api调用中获得了时间,包括夏令时偏移量。所有这些都可以在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
                        }
                    }
                });
            }
        }
    });
}

在此处注册免费密钥:(无限制,但如果每秒请求超过1个,则排队)

查看Maxmind GeoLite2数据库。它包含了大多数IP地址(包括时区)的大陆/国家/城市和lat/lon的详细信息,如下所示

我在这里介绍如何编译PHP扩展,以及如何在PHP中使用mmdb数据库:


通过用户的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';
}
下面是一个使用将IP地址映射到时区的示例,例如向
https://ipapi.co//timezone/
&获取该IP地址的时区

PHP代码

file_get_contents('https://ipapi.co/1.2.3.4/timezone/');
准确率并非如其他人所说的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');
有时它在本地服务器上无法工作,所以请在服务器上尝试


编辑:此数据来自ip api.com,只要您每分钟不超过45个请求,并且不在商业上使用,这些数据就可以免费使用。查看他们的,不长的a页。

应用程序正在本地计算机上运行,但我希望通过服务器端的IP获取时区,而不是在本地计算机上。我希望本地复制GeoIP时区数据。时区非常困难,因为大多数国际化问题都是这样。如果您知道他们的当前时间,并且他们是否使用夏令时,那么您可以确定他们的时区。然而,弄清楚日光的说法是非常困难的(再次),这在理论上是一个好主意,除非你考虑到DST。这让我想哭。这是个好主意。DST也没什么区别,因为我们总是在服务器上存储GMT:)尽管你可能经常向用户提供“最佳猜测”自动完成的表单字段,在这种情况下,这绝对没有问题。什么问题没有问题?使用ip来近似时区没有问题。我同意。如果有信息可以帮助您的用户体验朝着正确的方向发展,而不损害用户交互,那么就使用它吧@威廉:当然可以,但一定要测试一下IP地址把你引向错误方向的情况,就像我提到的:来自英格兰的IP地址,美国东部标准的实际时区。这非常有帮助,节省了很多时间:
file_get_contents('https://ipapi.co/1.2.3.4/timezone/');
$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');