Get Timezone by Latitude and Longitude in PHP

I was going through a bunch of GPS data on a project recently and needed to know the local times of the files – a task that's impossible without knowing the local time zones. After a bit of research, I found that the folks over at GeoNames had created an awesome (and free!) web service that allows you to look up a time zone of a given point by latitude and longitude. Using PHP's built in cURL library and SimpleXML extension, I put together a function that goes straight from latitude and longitude to timezone. Here is that function:

1.   <?php
3.   function get_timezone($latitude,$longitude,$username) {
5.   	//error checking
6.   	if (!is_numeric($latitude)) { custom_die('A numeric latitude is required.'); }
7.   	if (!is_numeric($longitude)) { custom_die('A numeric longitude is required.'); }
8.   	if (!$username) { custom_die('A GeoNames user account is required. You can get one here:'); }
10.  	//connect to web service
11.  	$url = ''.$latitude.'&lng='.$longitude.'&style=full&username='.urlencode($username);
12.  	$ch = curl_init();
13.  	curl_setopt($ch, CURLOPT_URL, $url);
14.  	curl_setopt($ch, CURLOPT_HEADER, false);
15.  	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
16.  	$xml = curl_exec($ch);
17.  	curl_close($ch);
18.  	if (!$xml) { $GLOBALS['error'] = 'The GeoNames service did not return any data: '.$url; return false; }
20.  	//parse XML response
21.  	$data = new SimpleXMLElement($xml);
22.  	//echo '<pre>'.print_r($data,true).'</pre>'; die();
23.  	$timezone = trim(strip_tags($data->timezone->timezoneId));
24.  	if ($timezone) { return $timezone; }
25.  	else { $GLOBALS['error'] = 'The GeoNames service did not return a time zone: '.$url; return false; }
27.  }
29.  ?>

And, here's a quick example of the function in action (you'd need to replace demo with your own GeoNames account):

1.   $timezone = get_timezone(-33.8578101,151.2138672,'demo');
2.   echo $timezone;
3.   //returns "Australia/Sydney"

And, of course, you could take this a step further and go from city to time zone, or postal address to time zone, by looking up the latitude and longitude via Google's Geocoding API.


June 26, 2015, 11:23 am
hello I'm a newbie
Can you tell me how to print with your function also all other tags: countryCode countryName lat lng dstOffset gmtOffset rawOffset time sunrise sunset ?
Robert James Reese
June 27, 2015, 7:04 am
If you uncomment this line, you'll see all the available data printed out:

//echo ''.print_r($data,true).''; die();

Then, you can select which fields you want in the following lines.
October 21, 2016, 4:46 am
Very helpful snippet. Thank you!

Leave a Comment

Name and email are required. Your email will not be published.

This post was published on December 24th, 2014 by Robert James Reese in the following categories: cURL, Maps, and PHP. Before using any of the code or other content in this post, you must read and agree to our Terms & Conditions.