2010-06-27 2 views
16

Есть ли способ получить часовой пояс пользователя по их широте и долготе? И не только смещение, но и фактический часовой пояс, в котором они находятся.Получить имя часового пояса PHP из широты и долготы?

По существу, я ищу полярную противоположность DateTimeZone :: getLocation, которая возвращает широту и долготу в определенный часовой пояс.

+0

Да, это было .. Я раньше смотрел на geonames, но из того, что я мог сказать, не дал фактического часового пояса NAME. Мальчик был я неправ, и мальчик теперь я чувствую себя глупо. – Navarr

ответ

6

географических названия должны делать работу хорошо:

http://www.geonames.org/

Они также есть библиотека PHP.

+3

GeoNames находит часовой пояс для ближайшей записи в своей базе данных. Если эта запись находится на другой стороне границы часового пояса, это будет неправильно. –

-1

API-интерфейс Yahoo предоставляет информацию о часовом поясе через обратную геолокацию.

Проверьте это.

http://developer.yahoo.com/geo/placefinder/guide/requests.html

+0

yahoo перестали поддерживать свои GPS-продукты в прошлом году и лицензировали технологию для Nokia, а не для компании с лучшими перспективами на будущее, если только они не уволили своего начальника разработки Microsoft и не присоединились к андроидному андеррайтеру до того, как компания закончится. –

-1

Как о поиске ближайшей точки к одному в списке всех мест часовых поясов? Интересно, насколько это верно?

ОБНОВЛЕНИЕ: В конце концов, я придумал этот фрагмент, который работает для меня. Это будет хорошо работать для всех мест, но может быть неточным для тех, кто находится близко к границам.

/** 
    * 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]; 

    } 
+5

Это очень неверно, поскольку он обрабатывает каждый часовой пояс как единую широту и широту. Это будет немного неточно близко к границам, оно будет ужасно неточным на обширных территориях земного шара. –

+1

@James D, я согласен, что вы не можете полагаться на это решение, если вам нужно точное решение идентификации часового пояса, но совершенно нормально предлагать пользователю выбирать среди списка часовых поясов, наиболее близких к его местоположению. Я считаю этот подход лучше, чем просто предоставление огромного списка часовых поясов. – Dziamid

+0

Часовой пояс не основан исключительно на LatLong, есть и политические соображения. Сингапур находится в том же часовом поясе, что и Гонконг, хотя он значительно к западу от Гонконга, и хотя он находится в той же долготе, что и Джакарта, на час раньше Джакарты. Попытка вычисления часового пояса строго на lat/long без их отображения - плохая идея. – Shreeni

0

Я недавно разработал решение часового пояса в хакатоне продолжительностью 8 часов. Он быстро собрался вместе, и я хотел бы развивать его дальше и продавать его как продукт, но поскольку для меня нет возможности это сделать, я открыл его в my github.

Существует также demo, но он может упасть, если он попадает в пределы ресурсов. Это бесплатный webapp в Google App Engine.

Вы можете определенно оптимизировать/увеличить это в дальнейшем, используя время, пространство, данные - в соответствии с вашими потребностями.

+0

Вы пропустили «PHP» в вопросе? Существует гораздо лучшее решение для уже доступных Python: https://github.com/MrMinimal64/timezonefinder – hackel

15

Для тех, кто хочет получить часовой пояс от код страны, широта и долгота. (легко получить его, если на вашем сервере установлен модуль геоинформации)

Попробуйте это, я добавил расчет расстояния - только для тех стран, которые имеют несколько часовых поясов. Ах, а код страны - это двухбуквенный код ISO.

// [email protected] 

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') ; 
+0

Возможно, это лучший ответ. Мне нужно было провести некоторое тестирование. Почему код страны вообще? Существуют ли местоположения в разных странах? – Navarr

+0

Хорошее решение. Благодарю. – ineersa

+0

Отличный, ... некогда неправильный часовой пояс, но работает точный при использовании с кодом страны – rushil

2

насчет часового пояса API 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' 
) 

, но есть некоторые ограничения

Google Time Zone API имеет следующие ограничения на месте:

пользователей свободного API:
2500 запросов за 24-часовой период.
10 запросов в секунду.

Карты для деловых клиентов:
100 000 запросов за 24 часа.
10 запросов в секунду.

Смежные вопросы