Get PHP Timezone Name from Latitude and Longitude?
有没有办法通过纬度和经度获得用户的时区? 而不只是偏移量,而是它们所处的实际时区。
基本上,我正在搜索DateTimeZone :: getLocation的极性相反,它返回某个时区的纬度和经度。
对于那些想要从国家代码,纬度和经度获得时区的人。 (如果您的服务器上安装了geoip模块,则很容易获得)
试试这个,我添加了一个距离计算 - 仅适用于那些有多个时区的国家。
啊,国家代码是两个字母的ISO代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // ben@jp 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'; } //timezone for one NY co-ordinate echo get_nearest_timezone(40.772222,-74.164581) ; // more faster and accurate if you can pass the country code echo get_nearest_timezone(40.772222, -74.164581, 'US') ; |
Geonames应该很好地完成这项工作:
http://www.geonames.org/
他们还有一个php库。
一个很好的资源是Google时区API。
文档:https://developers.google.com/maps/documentation/timezone/
它需要
1 2 3 4 5 6 7 | array( 'dstOffset' => (int) 3600, 'rawOffset' => (int) -18000, 'status' => 'OK', 'timeZoneId' => 'America/New_York', 'timeZoneName' => 'Eastern Daylight Time' ) |
......但是有一些限制:
[updated 2019] The Google Time Zone API has usage limits in place. Basically, billing must be enabled on your project, but a $200 USD"Google Maps Platform credit" is applied each month (so in most cases your first 40,000 Time Zone API calls/month would be free of charge).
- Full details here and here.
我最近在8小时的黑客马拉松中做了一个时区解决方案。它很快就被整合在一起,我很乐意将它进一步发展并作为产品出售,但由于我无法做到这一点,我已经在我的github上开源了。
还有一个演示,但如果它达到资源限制可能会下降。它是Google App Engine上的免费网络应用程序。
您可以在运行时间,空间,数据方面进一步优化/扩充,以满足您的需求。
Yahoo places API通过反向地理定位提供时区信息。
看看这个。
http://developer.yahoo.com/geo/placefinder/guide/requests.html
如何找到所有时区位置列表中最接近的点?我想知道这有多准确?
更新:
最后,我想出了适合我的这个片段。这适用于所有位置,但对于靠近边界的人可能不准确。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** * Attempts to find the closest timezone by coordinates * * @static * @param $lat * @param $lng */ public static function getClosestTimezone($lat, $lng) { $diffs = array(); foreach(DateTimeZone::listIdentifiers() as $timezoneID) { $timezone = new DateTimeZone($timezoneID); $location = $timezone->getLocation(); $tLat = $location['latitude']; $tLng = $location['longitude']; $diffLat = abs($lat - $tLat); $diffLng = abs($lng - $tLng); $diff = $diffLat + $diffLng; $diffs[$timezoneID] = $diff; } //asort($diffs); $timezone = array_keys($diffs, min($diffs)); return $timezone[0]; } |