如何通过PHP中的IP地址获取时区[重复]
Posted
技术标签:
【中文标题】如何通过PHP中的IP地址获取时区[重复]【英文标题】:How to get Time Zone through IP Address in PHP [duplicate] 【发布时间】:2010-10-19 02:44:43 【问题描述】:我想通过 php 中的 IP 地址获取时区。实际上,我有一个将在客户端机器上运行的应用程序。我有客户端机器的 IP 地址。但我无法获取每台客户端机器的时区。
【问题讨论】:
试试这个:sanjaykumarns.blogspot.com/p/… 【参考方案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+"×tamp="+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/<IP-Address>/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,不是很长的一页。
【讨论】:
非常有帮助为我节省了很多时间以上是关于如何通过PHP中的IP地址获取时区[重复]的主要内容,如果未能解决你的问题,请参考以下文章