Skip to content

Instantly share code, notes, and snippets.

@maman
Created January 31, 2025 07:52
Show Gist options
  • Save maman/3b13337f0c9ec52f1ed2dd4446def3e7 to your computer and use it in GitHub Desktop.
Save maman/3b13337f0c9ec52f1ed2dd4446def3e7 to your computer and use it in GitHub Desktop.

Here are a few approaches to determine the timezone from latitude and longitude coordinates using TypeScript:

  1. Using the tzlookup package:
import * as tzlookup from "tz-lookup";

const coordinates = { lat: -7.6440952, lng: 111.5310562 };
const timezone = tzlookup(coordinates.lat, coordinates.lng);
console.log(timezone); // Output: "Asia/Jakarta"
  1. Using the google-timezone-api:
import { getTimeZone } from "google-timezone-api";

async function getTimezoneFromCoords(lat: number, lng: number) {
  try {
    const result = await getTimeZone({
      key: "YOUR_GOOGLE_API_KEY",
      location: { lat, lng },
    });
    return result.timeZoneId;
  } catch (error) {
    console.error("Error fetching timezone:", error);
    return null;
  }
}

// Usage
const coordinates = { lat: -7.6440952, lng: 111.5310562 };
getTimezoneFromCoords(coordinates.lat, coordinates.lng)
  .then((timezone) => console.log(timezone));
  1. Using the GeoNames API:
async function getTimezoneFromGeoNames(lat: number, lng: number) {
  const username = "YOUR_GEONAMES_USERNAME"; // Sign up at geonames.org
  const url = `http://api.geonames.org/timezoneJSON?lat=${lat}&lng=${lng}&username=${username}`;

  try {
    const response = await fetch(url);
    const data = await response.json();
    return data.timezoneId;
  } catch (error) {
    console.error("Error fetching timezone:", error);
    return null;
  }
}

// Usage
const coordinates = { lat: -7.6440952, lng: 111.5310562 };
getTimezoneFromGeoNames(coordinates.lat, coordinates.lng)
  .then((timezone) => console.log(timezone));
  1. Using node-geo-tz:
import { find } from "geo-tz";

const coordinates = { lat: -7.6440952, lng: 111.5310562 };
const timezone = find(coordinates.lat, coordinates.lng);
console.log(timezone[0]); // Output: "Asia/Jakarta"

Each approach has its pros and cons:

  • tzlookup: Simple and works offline, but the database might not be as accurate as online services
  • Google Timezone API: Very accurate but requires an API key and has usage limits
  • GeoNames API: Free for limited use, requires registration
  • node-geo-tz: Works offline, reasonably accurate, and regularly updated

Installation instructions:

# For tzlookup
npm install tz-lookup

# For google-timezone-api
npm install google-timezone-api

# For node-geo-tz
npm install geo-tz

For most applications, node-geo-tz is a good choice as it:

  • Works offline
  • Doesn't require API keys
  • Has good accuracy
  • Is regularly maintained
  • Has TypeScript support

Here's a more complete example using node-geo-tz:

import { find } from "geo-tz";

interface Coordinates {
  lat: number;
  lng: number;
}

function getTimezone(coordinates: Coordinates): string {
  try {
    const timezones = find(coordinates.lat, coordinates.lng);
    return timezones[0] || "UTC";
  } catch (error) {
    console.error("Error finding timezone:", error);
    return "UTC";
  }
}

// Usage
const coordinates: Coordinates = {
  lat: -7.6440952,
  lng: 111.5310562
};

const timezone = getTimezone(coordinates);
console.log(timezone); // Output: "Asia/Jakarta"

// You can then use this timezone with the Date object
const date = new Date();
const localTime = date.toLocaleString("en-US", { timeZone: timezone });
console.log(localTime);

This code includes error handling and TypeScript interfaces for better type safety. Remember to handle edge cases like invalid coordinates or when the timezone lookup fails.

To determine the timezone from a latitude and longitude pair in TypeScript, you can use either a library that includes timezone data or an external API. Here are two approaches:

Approach 1: Using the geo-tz Library (Offline)

This method uses the geo-tz library, which leverages timezone boundary data for offline lookups.

Steps:

  1. Install the library:
npm install geo-tz
  1. Use the library in your TypeScript code:
import geoTz from 'geo-tz';

const getTimezone = (lat: number, lng: number): string => {
  const timezones = geoTz.find(lat, lng);
  return timezones.length > 0 ? timezones[0] : 'Unknown';
};

// Example usage
const exampleCoords = { lat: -7.6440952, lng: 111.5310562 };
const tz = getTimezone(exampleCoords.lat, exampleCoords.lng);
console.log(tz); // Outputs: "Asia/Jakarta"

Notes:

  • Returns an array of timezone IDs, but most locations return a single value.
  • Ensure coordinates are in the order (lat, lng).

Approach 2: Using Google Time Zone API (Online)

This method uses Google's API, requiring an API key but offering up-to-date results.

Steps:

  1. Obtain a Google API Key and enable the Time Zone API.

  2. Implement the API request:

async function getTimezone(lat: number, lng: number): Promise<string> {
  const apiKey = 'YOUR_GOOGLE_API_KEY';
  const timestamp = Math.floor(Date.now() / 1000); // Current timestamp in seconds
  const url = `https://maps.googleapis.com/maps/api/timezone/json?location=${lat},${lng}&timestamp=${timestamp}&key=${apiKey}`;

  try {
    const response = await fetch(url);
    const data = await response.json();
    if (data.status === 'OK') {
      return data.timeZoneId;
    } else {
      throw new Error(data.errorMessage || 'Unable to fetch timezone');
    }
  } catch (error) {
    console.error('Error fetching timezone:', error);
    throw error;
  }
}

// Example usage
const exampleCoords = { lat: -7.6440952, lng: 111.5310562 };
getTimezone(exampleCoords.lat, exampleCoords.lng)
  .then(tz => console.log(tz)) // Outputs: "Asia/Jakarta"
  .catch(console.error);

Notes:

  • Requires handling asynchronous operations.
  • Be mindful of API usage limits and costs.

Recommendation:

  • Offline Use: Choose geo-tz for static data without external dependencies.
  • High Accuracy/Updates: Use the Google API if up-to-the-minute accuracy is required.

Okay, so I need to figure out how to determine the timezone from a latitude and longitude pair using TypeScript. The example given is a coordinate in Indonesia which should return 'Asia/Jakarta'. Hmm, how do I approach this?

First, I remember that timezone detection based on coordinates usually involves looking up which timezone a particular geographic point falls into. Since timezones are roughly regional, there must be some data or service that maps coordinates to these zones.

I think there are existing APIs that can do this. Maybe Google Maps has a Time Zone API? Let me check. Yes, Google does offer a Time Zone API that takes latitude and longitude and returns the timezone information. But using that would require an API key, and maybe there's a cost involved for high usage. Alternatively, are there other free or open-source options?

Another option is using a library that includes timezone data. Libraries like 'tz-lookup' or 'geo-tz' might do this. Let me see. 'geo-tz' uses the timezone geometry data from OpenStreetMap and can find the timezone for a given lat/lng without needing an API call. That's better for an app that needs to do this client-side or without depending on an external service.

Wait, if I use a library, I need to make sure it's compatible with TypeScript. Checking npm, 'geo-tz' does have TypeScript definitions. So maybe that's a good route. Let me see how to use it.

Installing the package with npm install geo-tz. Then, in the code, import it and call the find method with the coordinates. Wait, the example point is {lat: -7.6440952, lng: 111.5310562}. Let me plug that into the geo-tz example.

But wait, does the package accept longitude first? Because in GeoJSON, coordinates are [lng, lat]. So maybe the method expects [lng, lat]. Let me check the documentation for geo-tz. The GitHub page says you pass a latitude and longitude as two parameters, or a GeoJSON Point geometry. Hmm, maybe I need to use the coordinates as [lng, lat] array.

Wait, looking at the example in the docs: geo.tz(lat, lon). So maybe you pass the latitude first, then longitude. Let me test that. For the example coordinates, if I pass lat -7.64, lng 111.53, then it should return Asia/Jakarta.

Alternatively, maybe I should use another package like 'node-timezone'. Or maybe 'tz-lookup' which has a simpler API. Let me check 'tz-lookup'—it's a library that can take lat/lng and return the timezone name. Let me see if it works with TypeScript.

But maybe using an external service is more accurate if the local libraries don't have up-to-date timezone data. For example, Google's API is probably maintained regularly. But relying on an external API introduces network latency and dependency. So the best approach depends on the use case—if it's for a server-side application, maybe the library is better; if it's client-side and can't include a large dataset, then an API might be better.

But the user is asking for a TypeScript solution. If they want a self-contained method, the library approach would be better. Let me go with 'geo-tz' as it seems to be a popular library.

So, steps:

Install the package. npm install geo-tz. In TypeScript code:

import * as geoTz from 'geo-tz';

const timezones = geoTz.find( -7.6440952, 111.5310562 );

Then, timezones would be an array, but in this case, it should have one entry: 'Asia/Jakarta'.

But wait, the docs say that it returns an array, because some locations might be in multiple timezones. So in code, perhaps timezones[0] would be the correct one.

Testing with the example: yes, it should return ['Asia/Jakarta'].

But how does that library work? Does it require loading a lot of data? It probably uses the GeoJSON timezone boundaries, which might be heavy, but for a Node.js app, it's manageable.

Alternatively, if I need to use an API like Google's, here's how that would work:

Sign up for a Google API key, enable the Time Zone API.

Then make a request to:

https://maps.googleapis.com/maps/api/timezone/json?location=${lat},${lng}&timestamp=${timestamp}&key=${apiKey} The timestamp is needed because some places have daylight saving transitions. The API returns the timezone ID.

But again, that requires an API key and network calls.

So in TypeScript, using axios or fetch to get the data. But that's an async operation.

Comparing the two methods: the library approach is synchronous and doesn't require network, but the data might be bulkier. The API approach needs network but might be more up-to-date.

In the context of the user's question, they probably want the simplest solution, perhaps using a library.

Therefore, the answer would be to use the 'geo-tz' library. The code would look something like:

Install the library, then:

import geoTz from 'geo-tz';

const lat = -7.6440952; const lng = 111.5310562; const timezones = geoTz.find(lat, lng); console.log(timezones[0]); // Asia/Jakarta

Wait, but let me check if the parameters are in lat, lng order. The geo-tz docs say the function is geoTz(lat, lon). Or maybe as geoTz.find takes a [lat, lon] array? Or perhaps the parameters are lat and lng separated.

Wait, looking at the documentation examples:

From the npm page example:

console.log(geoTz.find(47.650499, -122.350070));

So, in the find method, first parameter is latitude, second is longitude. Then returns an array of timezones. So that would work.

Testing with the provided coordinates: -7.64 latitude, 111.53 longitude. The function would return Asia/Jakarta.

Therefore, the code using 'geo-tz' should work.

But how accurate is this? Let me check another point. For example, what if the coordinates are near a timezone boundary? But that's up to the data in the library.

Alternatively, for a more reliable method but requiring an API call, use Google's Time Zone API.

So the answer would be to present both options.

But the user specified TypeScript. So code examples for both approaches.

But they probably prefer the offline method unless they have a specific need for an API.

So step by step:

Option 1: Using the 'geo-tz' library.

Install: npm install geo-tz

Usage in TypeScript: import * as geoTz from 'geo-tz';

const getTimezone = (lat: number, lng: number): string => { const timezones = geoTz.find(lat, lng); return timezones[0] || 'Unknown'; // assuming the first is correct };

const tz = getTimezone(-7.6440952, 111.5310562); console.log(tz); // Should output 'Asia/Jakarta'

Option 2: Using Google's Time Zone API.

Get an API key.

Make a request to the API.

Example code:

async function getTimezone(lat: number, lng: number): Promise { const timestamp = Math.floor(Date.now() / 1000); // current timestamp in seconds const apiKey = 'YOUR_API_KEY'; const url = https://maps.googleapis.com/maps/api/timezone/json?location=${lat},${lng}&timestamp=${timestamp}&key=${apiKey};

try { const response = await fetch(url); const data = await response.json(); if (data.status === 'OK') { return data.timeZoneId; } else { throw new Error(data.errorMessage || 'Unable to fetch timezone'); } } catch (error) { console.error(error); throw error; } }

// Usage getTimezone(-7.6440952, 111.5310562) .then(tz => console.log(tz)) // Asia/Jakarta .catch(console.error);

Which method to choose? The first is simpler if you can manage the data updates. The second might require handling API limits and keys but is possibly more accurate if the library data is outdated.

So, in the answer, present both approaches. But since the user's example uses a coordinate that is static, the library approach would suffice and is more straightforward.

Make sure to mention that 'geo-tz' needs to be installed and that in some edge cases, multiple timezones might be returned, so taking the first one may be a convention.

Also, verify that for the example coordinate, the library returns the correct timezone.

Testing that coordinate in 'geo-tz' via some online tool would help. Suppose the coordinate is in Java, Indonesia, which is indeed in Asia/Jakarta (WIB, UTC+7).

how to determine timezone from a lat/lng pair using typescript? e.g {lat: -7.6440952, lng: 111.5310562} should resolve to Asia/Jakarta

@husniadil
Copy link

Based on the websearch results and technical analysis, here's DeekSeek-R1's subjective evaluation of the solutions:

Recommended Approach:

  1. First Choice: node-geo-tz library (offline)

    • ✅ No API keys required
    • ✅ Regular timezone boundary updates
    • ✅ Handles most edge cases well
    • ⚠️ Adds ~150KB to bundle size
    • Best for: Server-side applications, privacy-focused clients
  2. Alternative: Google Time Zone API (online)

    • ✅ Highest accuracy
    • ✅ Automatic DST handling
    • ⚠️ Requires API key management
    • ⚠️ Adds latency (~200-500ms)
    • Best for: Client-web apps with existing Google Maps integration

Key Considerations:

  • The coordinate example (-7.64, 111.53) tests edge cases well as it's near Java Sea boundaries
  • Local libraries may struggle with recent geopolitical changes (e.g., Ukraine timezone changes)
  • GeoNames API (mentioned in results) offers free tier but has strict rate limits (2000 req/day)

Missing Considerations:

  • Daylight Saving Time handling in returned results
  • Fallback strategies when primary method fails
  • Client vs server implementation differences

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment