Categories:

Displaying the Local Time of Any City using JavaScript and Google Time Zone API

Created: Nov 7th, 16'

There are no shortages of JavaScript's Date() related adventures since the object was introduced many life times ago, though they are for the most part confined to retrieving and manipulating the local time of the user's system. Getting the date and time of a specific location in the world using JavaScript has always been an elusive affair, as the Date object inherently operates on the user computer's time. While there are Date methods such as Date.getTimezoneOffset() and Date.getUTCDate() to help us derive the universal time, from there it's a slippery slope of navigating the complex world of International Time rules such as Daylight Savings Time in certain time zones before we can reliability get to the pot at the end of the rainbow that is the time of a specific location in the world. What we need is a database of time zones and Daylight Saving Times rules to peel away all the complexities and fallibility of relying on just the user's local time to derive the time for a specific location on earth. And that is where Google's Time Zone API comes in handy:

LA Time:
Toronto Time:
Paris Time

Setting Up Google Time Zone API

Google's Timezone API provides a simple interface to get the time zone and DST (Daylight Savings Time) offset of any location on earth. To use it, simply make a request to:

https://maps.googleapis.com/maps/api/timezone/json/?parameters

where "json" can be substituted with the string "xml" if you wish the returned data to be in XML instead of the JSON format, and parameters should consist of the following 3 pieces of info:

Expected parameters for Google Time Zone API call:

  • location: A comma-separated Latitude and Longitude tuple (ie: location=37.3711, -122.0375), representing the exact location to look up.
  • timestamp: The desired date and time expressed in seconds since midnight, January 1, 1970 UTC. The API uses the timestamp to determine whether or not Daylight Savings should be applied. Times before 1970 can be expressed as negative values.
  • key: Your application's API key. This free key is required to make requests to the API from your site.

We'll go over in detail in the next section how to define the first two parameters, though before all else, you need to first obtain a Google API key to access the Time Zone API from your site. To do so, simply follow the instructions laid out on this page. If you've already set up a API key and want to modify or retreive it again, jump straight to the Google Console page.

Here is an example of a fully well formed Time Zone API call string to Vancouver, Canada for the date Nov 4th, 2016:

https://maps.googleapis.com/maps/api/timezone/json?location=49.283436, -123.130429&timestamp=1478880000&key=YOUR_API_KEY

The returned data:

The returned data once the call has been made, via Ajax for example, is in the form of a JSON string:

{
   "dstOffset" : 3600,
   "rawOffset" : -28800,
   "status" : "OK",
   "timeZoneId" : "America/Vancouver",
   "timeZoneName" : "Pacific Daylight Time"
}

In Vancouver Canada, Daylight Savings Time for 2016 is in effect between March 13 to Nov 6. As the requested date Nov 4th 2016 falls within that range, the returned data reflects this. The "dstOffset" parameter (in seconds) tells us for that time and location, the DST (Daylight Savings) offset is 1 hour (3600 secs) relative to the Universal Time. The "rawOffset" property tells us the standard offset (in seconds again) of this time zone relative to Universal Time, aside from any Daylight Savings offset.

In a nutshell, the local time of any location is derived by adding the values of the "timestamp" parameter and the returned "dstOffset", and "rawOffset" values together. But that's just a little too simple an explanation, so lets keep digging.

Preparing the parameters for the current date/time of a specific location on earth

Lets put all that theory to work now to actually get the current date and time of a specific location in the world. How about Tokyo? Been there once, loved everything except the expensive transit! We need the Latitude and Longitude coordinates for Tokyo, plus the current Universal date and time as seconds since midnight, January 1, 1970 UTC for the "timestamp" parameter to construct the corresponding Time Zone request:

var loc = '35.731252, 139.730291' // Tokyo expressed as lat,lng tuple
var targetDate = new Date() // Current date/time of user computer
var timestamp = targetDate.getTime()/1000 + targetDate.getTimezoneOffset() * 60 // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC
var apikey = 'YOUR_TIMEZONE_API_KEY_HERE'

var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + loc + '&timestamp=' + timestamp + '&key=' + apikey

Lets go over how we derived the above values:

- Getting the Latitude and Longitude of a location

To get the Latitude and Longitude of a location using Google Maps, enter the desired address (in this case "Tokyo Japan") into Google Maps and press enter. Then, right click on the name of the location on the map ("Tokyo") to bring up a context menu. Select and click the menu item "What's here" to bring up a card of the location with its Latitude and Longitude shown at the bottom:

Alternatively, you can use a site like latlong.net to get those cryptic numbers.

- Getting the timestamp value for any date

The timestamp parameter of Google Time Zone API expects the desired date and time to be expressed in seconds since midnight, January 1, 1970 UTC. For the current time, this is calculated by first instantiating the date object to get the current local time of the user's computer, then adding to it its UTC offset (in minutes) using Date.getTimezoneOffset():

var targetDate = new Date() // Current date/time of user computer
var timestamp = targetDate.getTime()/1000 + targetDate.getTimezoneOffset() * 60 // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC

Since the timestamp parameter should be in seconds, we do a little Math to hammer the current date and its UTC offset into that unit. And there we have it, a timestamp representing the current time and date since midnight, January 1, 1970 UTC, just as the doctor ordered.

If the target date you're interested in is NOT the current date/time, simply pass in a specific date string into new Date() when instantiating it, such as:

var targetDate = new Date('December 25, 2025')

This is useful for future or past related applications, such as counting down to Christmas 2025 Tokyo Time. See the myriad of ways to instantiate a Date object here.

At the end the apicall variable now contains the Google Time Zone request we can make to get back some useful information:

var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + loc + '&timestamp=' + timestamp + '&key=' + apikey

Making that call- getting the time for a specific location on Earth

We're now ready to use Ajax to pick up the phone and call the Time Zone API using the request string we just constructed above. The returned data provides us with the correct time zone and DST offsets for Tokyo, with which we can then use to determine the correct date and time for the city:

var loc = '35.731252, 139.730291' // Tokyo expressed as lat,lng tuple
var targetDate = new Date() // Current date/time of user computer
var timestamp = targetDate.getTime()/1000 + targetDate.getTimezoneOffset() * 60 // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC
var apikey = 'YOUR_TIMEZONE_API_KEY_HERE'
var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + loc + '&timestamp=' + timestamp + '&key=' + apikey

var xhr = new XMLHttpRequest() // create new XMLHttpRequest2 object
xhr.open('GET', apicall) // open GET request
xhr.onload = function(){
	if (xhr.status === 200){ // if Ajax request successful
		var output = JSON.parse(xhr.responseText) // convert returned JSON string to JSON object
		console.log(output.status) // log API return status for debugging purposes
		if (output.status == 'OK'){ // if API reports everything was returned successfully
			var offsets = output.dstOffset * 1000 + output.rawOffset * 1000 // get DST and time zone offsets in milliseconds
			var localdate = new Date(timestamp * 1000 + offsets) // Date object containing current time of Tokyo (timestamp + dstOffset + rawOffset)
			console.log(localdate.toLocaleString()) // Display current Tokyo date and time
		}
	}
	else{
		alert('Request failed.  Returned status of ' + xhr.status)
	}
}
xhr.send() // send request

Output: 

Lets go over the important bits now:

  • We create a new instance of the XMLHttpRequest() (Level 2) to make an Ajax request to the Time Zone API. FYI XMLHttpRequest2 is an improved version over the original XMLHttpRequest object, and is supported in all modern browsers and IE10+. If you require greater browser support you can of course revert to the original version instead, but I like the simplicity of the newer version.
  • Inside xhr.onload, we check that the Ajax request was successful (status == 200), then retrieve the returned data (in JSON string format) and turn it into an actual JSON object using JSON.parse. The end result looks similar to this, but in the form of an object.
  • Inside the JSON object output, we check its status property to make sure the Time Zone API didn't run into any turbulence fetching the requested time zone info. A value of "OK" signals all went well, while any other value requires the pilot's attention. See here for the possible return values.
  • Now we're ready to get to work. We retrieve the DST offset and Time Zone offset values from the JSON object for the current time in the target location. We convert the two values into milliseconds before adding them up to derive a total offset.
  • The target location's date and time is calculated by adding up the value of the timestamp parameter with the total offset: timestamp + dstOffset + rawOffset. The unit is in milliseconds so that we can directly feed the result into JavaScript's Date() object to get the target date and time as a Date object.
  • From there on the sky's the limit on what we want to do with the current Tokyo time! In the above case, we simply opt to show it in local, human friendly format.

Speaking of the sky, lets climb a little higher with this local time endeavor. How about creating a live time display of any location on earth? We'll do that next.