Obtener el nombre de la zona horaria de PHP de latitud y longitud?

¿Hay alguna forma de obtener la zona horaria de un usuario por su latitud y longitud? Y no solo el desplazamiento, sino la zona horaria real en la que se encuentran.

Esencialmente, estoy buscando el polo opuesto de DateTimeZone :: getLocation, que devuelve la latitud y la longitud para una determinada zona horaria.

Geonames debería hacer el trabajo muy bien:

http://www.geonames.org/

También tienen una biblioteca php.

Para aquellos que quieren obtener la zona horaria del código de país, latitud y longitud . (fácil de obtener si tienes un módulo geoip instalado en tu servidor)

Pruebe esto, he agregado un cálculo de distancia, solo para aquellos países que tienen múltiples zonas horarias. Ah, y el código de país es un código ISO de dos letras.

// 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 '
'.$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') ;

¿Qué pasa con google zona horaria api

https://developers.google.com/maps/documentation/timezone/

toma latitude y longitude y devuelve una matriz como esta

 array( 'dstOffset' => (int) 3600, 'rawOffset' => (int) -18000, 'status' => 'OK', 'timeZoneId' => 'America/New_York', 'timeZoneName' => 'Eastern Daylight Time' ) 

pero hay algunos límites

La API de Google Time Zone tiene los siguientes límites:

Usuarios de la API gratuita:
2,500 solicitudes por período de 24 horas.
10 solicitudes por segundo.

Clientes de Maps for Business:
100.000 solicitudes por período de 24 horas.
10 solicitudes por segundo.

Hice una solución de zona horaria recientemente en un hackathon de 8 horas de duración. Se arma rápidamente y me encantaría desarrollarlo más y venderlo como un producto, pero como no hay forma de hacerlo, lo he abierto en mi github .

También hay una demostración, pero puede disminuir si alcanza los límites de recursos. Es una aplicación web gratuita en Google App Engine.

Definitivamente puede optimizar / boost esto en tiempo real (tiempo de ejecución, espacio, datos) para satisfacer sus necesidades.

La API de lugares de Yahoo proporciona información de zona horaria a través de geolocalización inversa.

Echale un vistazo.

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

¿Qué hay de encontrar el punto más cercano al que está en la lista de todas las ubicaciones de la zona horaria? Me pregunto qué tan exacto es esto?

ACTUALIZACIÓN: Eventualmente, se me ocurrió este fragmento que funciona para mí. Esto funcionará bien para todas las ubicaciones, pero puede no ser exacto para las personas cercanas a las fronteras.

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