Lookup
Find the time zone at any latitude and longitude, on land or at sea. The answer carries the
same timezone block as Retrieve a time zone, so one
call gives you the local time, the UTC offset and the next clock change.
At a glance
GET /v1/lookup?lat=48.8566&lon=2.3522
| Parameter | Required | Description |
|---|---|---|
lat |
yes | Latitude in decimal degrees, from -90 to 90, like 40.7128. |
lon |
yes | Longitude in decimal degrees, from -180 to 180, like -74.006. lng works too; send only one. |
at |
no | Compute the times at this moment instead of now: an ISO 8601 datetime or a Unix timestamp. |
Coordinates are rounded to 6 decimals, about 11 cm. Exponents, like the 5e-7 some languages
write for small numbers, are read. Commas and spaces inside a number are rejected with a
422.
A datetime in at without an offset is read as UTC, not as local time at the point. Add Z
or an offset, as in the example below.
Example — the local time at a delivery address
A courier app has the drop-off point's coordinates and needs the customer's local time:
curl "https://api.timezone.io/v1/lookup?lat=48.8566&lon=2.3522&at=2026-01-15T12:00:00Z" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"data": {
"query": { "latitude": 48.8566, "longitude": 2.3522 },
"kind": "land",
"timezone": {
"iana": "Europe/Paris",
"display_name": "Paris",
"observes_dst": true,
"is_mainland": true,
"coordinates": { "latitude": 48.86666, "longitude": 2.33333 },
"country": { "code": "FR", "name": "France" },
"current": {
"datetime": "2026-01-15T13:00:00+01:00",
"utc_datetime": "2026-01-15T12:00:00Z",
"utc_offset": "+01:00",
"utc_offset_seconds": 3600,
"abbreviation": "CET",
"name": "Central European Standard Time",
"is_dst": false
},
"standard": {
"utc_offset": "+01:00",
"utc_offset_seconds": 3600,
"abbreviation": "CET",
"name": "Central European Standard Time"
},
"dst": {
"savings_seconds": 3600,
"next_transition": {
"type": "spring_forward",
"at": "2026-03-29T01:00:00Z",
"utc_offset_after": "+02:00",
"abbreviation_after": "CEST",
"clock_change_seconds": 3600
}
},
"links": {
"self": "https://api.timezone.io/v1/timezones/Europe/Paris",
"country": "https://api.timezone.io/v1/countries/FR",
"abbreviation": "https://api.timezone.io/v1/abbreviations/central-european-standard-time",
"web": "https://timezone.io/iana/Europe/Paris"
}
},
"alternatives": []
},
"meta": {
"tzdb_version": "2026d",
"generated_at": "2026-09-27T09:00:00+00:00",
"boundaries": {
"version": "2026d",
"attribution": "Contains information from timezone-boundary-builder (https://github.com/evansiroky/timezone-boundary-builder), made available under the Open Database License (ODbL) 1.0 (https://opendatacommons.org/licenses/odbl/1-0/). Boundary data © OpenStreetMap contributors (https://www.openstreetmap.org/copyright)."
}
}
}
Where zones overlap
Where two zones' boundaries overlap, you get every zone: the one with the smallest area comes
first, and the others are listed in alternatives with "reason": "overlap". Most overlaps
are disputed areas. A few are narrow slivers along borders and coasts in the source data,
where two maps don't quite meet; the widest is about 1 km. In three areas the smallest zone
is not the administering authority's clock, so we put that authority's zone first: Xinjiang
(Asia/Shanghai, +08, before Asia/Urumqi), Abkhazia (Europe/Moscow before
Asia/Tbilisi) and Kalapani (Asia/Kolkata before Asia/Kathmandu). Ürümqi:
curl "https://api.timezone.io/v1/lookup?lat=43.8256&lon=87.6168" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"data": {
"query": { "latitude": 43.8256, "longitude": 87.6168 },
"kind": "land",
"timezone": {
"iana": "Asia/Shanghai",
"display_name": "Shanghai",
"observes_dst": false,
"country": { "code": "CN", "name": "China" },
"current": {
"utc_offset": "+08:00",
"abbreviation": "CST",
"is_dst": false,
"…": "…"
},
"…": "the full block, as above"
},
"alternatives": [
{
"reason": "overlap",
"timezone": {
"iana": "Asia/Urumqi",
"display_name": "Urumqi",
"country": { "code": "CN", "name": "China" },
"current": {
"utc_offset": "+06:00",
"abbreviation": "+06",
"is_dst": false
},
"observes_dst": false,
"links": {
"self": "https://api.timezone.io/v1/timezones/Asia/Urumqi"
}
}
}
]
}
}
The primary follows China's official UTC+08:00 time. Some residents also use local Xinjiang Time (UTC+06:00), returned as an alternative. Show both when it matters.
At sea
Outside any country's territorial waters (12 nautical miles from the coast), the answer is a
nautical zone: Etc/GMT or Etc/GMT±N, each 15° of longitude wide, centred on multiples of
15°, except Etc/GMT+12 and Etc/GMT-12, which are 7.5° wide and meet at the 180th meridian.
kind is "ocean", country and the links are null, and so are coordinates.latitude
and .longitude.
curl "https://api.timezone.io/v1/lookup?lat=30&lon=-40" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"data": {
"query": { "latitude": 30, "longitude": -40 },
"kind": "ocean",
"timezone": {
"iana": "Etc/GMT+3",
"display_name": "UTC-03:00 (international waters)",
"observes_dst": false,
"coordinates": { "latitude": null, "longitude": null },
"country": null,
"current": {
"utc_offset": "-03:00",
"abbreviation": "-03",
"name": null,
"…": "…"
},
"links": {
"self": null,
"country": null,
"abbreviation": null,
"web": null
},
"…": "…"
},
"alternatives": []
}
}
The sign in these zone identifiers is inverted: Etc/GMT+3 is three hours behind UTC.
That's an old Unix convention. Read current.utc_offset, which always uses the usual sign.
Ships often keep another time in practice; this is the zone the map gives.
The same nautical zones cover the part of Antarctica no country claims, roughly 90°W to
150°W. South of 60°S, at sea or on that land, the label reads like UTC-08:00 (Antarctica)
instead of "international waters". kind is still "ocean".
Response fields
| Field | Description |
|---|---|
query.latitude, .longitude |
The point that was looked up, rounded to 6 decimals. 180 stays 180. |
kind |
land (a country's territory, including territorial waters) or ocean (a nautical zone: international waters, and unclaimed Antarctica). |
timezone |
The zone at the point, in the shape of Retrieve a time zone, computed at at. |
alternatives |
Other zones for the same point, each with a reason. Empty for almost every point. |
alternatives[].reason |
overlap: another zone's boundary also contains the point. antimeridian: the zone across the 180° line, when you send exactly lon=180 or -180. |
alternatives[].timezone |
A short time-zone row, with current computed at at. |
meta.boundaries |
Which boundary release answered (version), and the credit its licence asks for (attribution). |
Borders and edge cases
- On a border. A point exactly on a border belongs to the zone east of it, or north of it on an east–west border. At 6 decimals that strip is about 11 cm wide.
- The 180th meridian.
lon=180andlon=-180are both valid and never wrapped. Each answers for its own side, and lists the zone on the other side as anantimeridianalternative when it differs. - The poles.
lat=90returnsEtc/GMTat every longitude, by convention.lat=-90returnsAntarctica/McMurdo, the zone that covers the South Pole. - The country is the zone's.
timezone.countryis the country the zone belongs to, not the country at your point. Northern Vietnam usesAsia/Bangkok, so its country is Thailand. - The coordinates are the zone's.
timezone.coordinatesis the zone's reference city; your point is inquery. - Borders are today's.
atmoves the clock rules (past or future offsets and daylight saving), not the borders. - Maps can be wrong. Borders come from OpenStreetMap, and some communities near a border keep their neighbour's time.
- Overlaps. Every zone whose boundary contains the point is returned; the smallest comes first, except in Xinjiang, Abkhazia and Kalapani, where the administering authority's zone does (see "Where zones overlap").
Caching
A point's zone only changes when meta.boundaries.version changes, a few times a year. You
may cache the zone for a point and compute times yourself; call again when the version
changes, or when you need our live current block.
Data and method
Boundaries come from timezone-boundary-builder's
timezones-with-oceans release (the version is in meta.boundaries.version), which is built
from OpenStreetMap. At launch that is release 2026d, file
https://github.com/evansiroky/timezone-boundary-builder/releases/download/2026d/timezones-with-oceans.geojson.zip,
sha256 e391c92c7b90339c3afe8558082b4532b8d9afc9daad68da31f4569a1ca61034. Later releases are
checked against the sha256 digest GitHub publishes for them. We re-encode the data without
loss, fill its gaps and index it:
- coordinates × 10⁶ as 32-bit integers, with no simplification and no clipping;
- a 1° grid of candidate zones, and 0.02° latitude bands of edges;
- an even-odd ray-crossing test toward the east, where a point on an edge belongs to the zone east or north of it;
- where zones overlap, every zone is returned, smallest area first. Area is the spherical area R²/2 · Σ(λ₂ − λ₁)(2 + sin φ₁ + sin φ₂) of each zone's outer rings minus its holes, with R = 6,371,008.8 m; equal areas are ordered by zone identifier. The index stores these areas. Three areas are the exception, listed above under "Where zones overlap": there the zone whose time is actually kept comes first;
- the source can leave gaps between zones. A gap at least a millionth of a degree wide is
filled from the neighbouring zone that shares the longest border with it, and we refuse to
publish if a gap is wider than 1,000 millionths of a degree (about 110 m), which would mean
a zone is missing (release
2026dhas no such gap). Narrower slivers remain where a land border meets the edge of an ocean zone and the ocean zone's copy of that border was rounded a few centimetres away from it; no polygon drawn on the millionth-of-a-degree grid can close them, so we check, for every such sliver, that the nautical zone for its longitude is the zone next to it, and refuse to publish otherwise. A point in one of them gets that nautical zone.
Contains information from timezone-boundary-builder (https://github.com/evansiroky/timezone-boundary-builder), made available under the Open Database License (ODbL) 1.0. Boundary data © OpenStreetMap contributors.