【问题标题】:How to get Time Zone through IP Address in PHP [duplicate]如何通过PHP中的IP地址获取时区[重复]
【发布时间】:2010-10-19 02:44:43
【问题描述】:

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

【问题讨论】:

标签: php time timezone ip


【解决方案1】:

如果您在本地机器上运行它,您可以检查配置的时区。
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获取时区,而不是在本地机器上。
  • 我希望在本地复制 GeoIP 时区数据。
【解决方案2】:

没有绝对确定的方法可以获取客户的时区,但是如果您让客户从他们的机器上提交日期和时间,您可以根据它相对于 GMT 的时间来计算它。因此,如果在他们的机器上是晚上 7:00 并且是格林威治标准时间上午 12:00,那么您可以确定他们是格林威治标准时间或 (EST/DST) 的 -5

【讨论】:

  • 时区非常困难,因为大多数国际化问题都是如此。如果您知道他们的当前时间并且他们是否在夏令时,那么您可以确定他们的时区。然而,弄清楚白天的说法非常困难(再次)
  • 在您考虑夏令时之前,这在理论上是个好主意。这让我想哭。
  • 这是个好主意。 DST 并没有什么不同,因为我们总是将 GMT 存储在服务器上 :)
【解决方案3】:

甚至不能依靠 IP 地址映射到一个国家;如果您还想获得时区,那您就如履薄冰。您最好让客户端向您发送时区,也许在标题中。

请参阅Tor: anonymity online,了解停止将 IP 地址用于非设计用途的另一个原因。

【讨论】:

  • 通常,尽管您可能会向用户提供“最佳猜测”自动完成的表单字段,但在这种情况下,这绝对没有问题。
  • 什么没问题?
  • 使用 ip 来估算时区并没有错。
  • 我同意。如果有信息可以在不损害用户交互的情况下帮助您的 UX 朝着正确的方向发展,请使用它!
  • @Willem: 当然可以,但一定要测试一下 IP 地址将你引向 错误 方向的情况,就像我提到的情况一样:IP address from England, actual时区美国东部标准。
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    这不是直截了当的,但我得到了时间,包括使用 jquery 和 php 的 2 个 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
                            }
                        }
                    });
                }
            }
        });
    }
    

    定位.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 个,则排队)

    【讨论】:

      【解决方案6】:

      查看 Maxmind GeoLite2 数据库。它包含大多数 IP 地址的大陆/国家/城市和纬度/经度的详细信息,包括 time_zone,如下所示。

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

      Intro to Maxmind GeoLite2 with Kohana PHP

      【讨论】:

        【解决方案7】:

        通过用户的 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';
        }
        

        【讨论】:

          【解决方案8】:

          这是一个使用location API 的示例,它将 IP 地址映射到时区,例如向https://ipapi.co/&lt;IP-Address&gt;/timezone/ 发送请求并获取该 IP 地址的时区。

          PHP 代码

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

          准确率并非像其他人所说的那样是 100%。

          【讨论】:

            【解决方案9】:
            $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 个请求并且不用于商业用途。见他们的TOS,不是很长的一页。

            【讨论】:

            • 非常有帮助为我节省了很多时间
            猜你喜欢
            • 1970-01-01
            • 2020-12-19
            • 2014-03-16
            • 1970-01-01
            • 2017-03-09
            • 1970-01-01
            • 2015-12-19
            • 1970-01-01
            • 2018-06-22
            相关资源
            最近更新 更多