Есть ли способ получить часовой пояс пользователя по их широте и долготе? И не только смещение, но и фактический часовой пояс, в котором они находятся.
По сути, я ищу полярную противоположность DateTimeZone :: getLocation, которая возвращает широту и долготу для определенного часового пояса.
Для тех, кто хочет получить часовой пояс из кода страны, широты и долготы . (легко получить его, если на вашем сервере установлен модуль geoip)
Попробуйте это, я добавил расчет расстояния – только для тех стран, у которых есть несколько часовых поясов. Ах, а код страны – двухбуквенный код ISO.
// 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') ;
Как насчет часовой пояс google
https://developers.google.com/maps/documentation/timezone/
он принимает latitude
и longitude
и возвращает массив как это
array( 'dstOffset' => (int) 3600, 'rawOffset' => (int) -18000, 'status' => 'OK', 'timeZoneId' => 'America/New_York', 'timeZoneName' => 'Eastern Daylight Time' )
но есть некоторые ограничения
API-интерфейс Google Time Zone имеет следующие ограничения:
Пользователи бесплатного API:
2500 запросов за 24 часа.
10 запросов в секунду.Карты для бизнес-клиентов:
100 000 запросов за 24 часа.
10 запросов в секунду.
Недавно я сделал часовое решение в хак-тане за 8 часов. Он быстро собрался, и я хотел бы развивать его дальше и продавать его как продукт, но поскольку для меня нет никакого способа сделать это, я открыл его в своем github .
Существует также демонстрация, но она может упасть, если она попадает в пределы ресурсов. Это бесплатный webapp в Google App Engine.
Вы можете определенно оптимизировать / увеличить это в дальнейшем, используя время, пространство, данные – в соответствии с вашими потребностями.
API-интерфейсы Yahoo предоставляет информацию о часовом поясе через обратную геолокацию.
Проверьте это.
http://developer.yahoo.com/geo/placefinder/guide/requests.html
Как насчет нахождения ближайшей точки в списке всех мест временного зонирования? Интересно, насколько это верно?
UPDATE: В конце концов, я придумал этот фрагмент, который работает для меня. Это будет хорошо работать для всех мест, но может быть неточным для тех, кто находится близко к границам.
/** * 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]; }