GET /v1/timezone
IANA timezone, UTC offset, DST flag and local time for a coordinate. By default everything is computed for the moment the request is served; pass at to compute the offset for a specific instant instead. Ocean points fall back to the nautical zone (Etc/GMT±H).
Request
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
lat | float | yes | — | Latitude, −90..90. |
lng | float | yes | — | Longitude, −180..180. |
at | string | no | now | ISO 8601 instant to compute the offset for, e.g. 2026-12-21T12:00:00Z. Include the timezone (a trailing Z or ±HH:MM) — the offset only makes sense for an absolute moment, so a value without one is read as UTC. |
Examples
# now
curl -H "X-API-Key: gi_live_..." \
"https://geoinsight.dev/v1/timezone?lat=52.2297&lng=21.0122"
# offset on a winter date (DST off): +01:00, not the summer +02:00
curl -H "X-API-Key: gi_live_..." \
"https://geoinsight.dev/v1/timezone?lat=52.2297&lng=21.0122&at=2026-12-21T12:00:00Z"
import requests
r = requests.get(
"https://geoinsight.dev/v1/timezone",
params={"lat": 52.2297, "lng": 21.0122},
headers={"X-API-Key": "gi_live_..."},
)
print(r.json()["timezone"])
const res = await fetch(
"https://geoinsight.dev/v1/timezone?lat=52.2297&lng=21.0122",
{ headers: { "X-API-Key": "gi_live_..." } },
);
const data = await res.json();
console.log(data.timezone);
Response
# GET …&at=2026-12-21T12:00:00Z
{
"timezone": "Europe/Warsaw",
"at": "2026-12-21T13:00:00+01:00",
"utc_offset": "+01:00",
"offset_seconds": 3600,
"dst": false,
"local_time": "2026-12-21T13:00:00+01:00",
"nautical": false
}
| Field | Type | Unit | Description |
|---|---|---|---|
timezone |
string | IANA | IANA zone identifier, e.g. Europe/Warsaw. Depends only on the coordinate, never on at — safe to cache per rounded coordinate more or less forever. For ocean points this is a fixed Etc/GMT±H zone (no DST) instead of a place name — see nautical. |
at |
string | ISO 8601 | The instant the rest of the block was computed for, in the point local time. Equals the request time when you did not pass at. Echoed so you can see which side of a DST change you landed on. |
utc_offset |
string | ±HH:MM | Offset from UTC at at, already including DST if in effect then. |
offset_seconds |
integer | s | The same offset in seconds — the form to use for arithmetic. Negative west of Greenwich. |
dst |
boolean | — | Whether daylight saving time is in effect at this location at at. Note the southern hemisphere is inverted relative to the northern. |
local_time |
string | ISO 8601 | Wall-clock time at the coordinate for at, with offset. Identical to at; kept for readers who expect this name. |
nautical |
boolean | — | true when the point lies outside every IANA land timezone (open ocean) and the fixed nautical zone was used as a fallback. Nautical zones have no DST, so their offset is the same for every at. |
timezone is effectively static per coordinate — cache it as long as you like. Everything else (utc_offset, offset_seconds, dst, local_time) depends on at, so cache those only against the exact at you asked for, never as a value that is true forever.
Ocean points
A coordinate outside every IANA land zone (open ocean) falls back to a fixed nautical zone Etc/GMT±H based on longitude. These zones have no DST, so dst is always false and the offset is the same for every at:
# mid-Atlantic: GET /v1/timezone?lat=30&lng=-40
{
"timezone": "Etc/GMT+3",
"at": "2026-08-11T13:00:00-03:00",
"utc_offset": "-03:00",
"offset_seconds": -10800,
"dst": false,
"local_time": "2026-08-11T13:00:00-03:00",
"nautical": true
}
Note the sign convention: Etc/GMT+3 is UTC−03:00 — the POSIX Etc/GMT zones invert the sign, which is a quirk of the tz database, not a bug. Trust offset_seconds.
Attribution & Data source
Timezone boundaries: timezone-boundary-builder, derived from OpenStreetMap — licensed under ODbL. See the timezone-boundary-builder project for attribution and terms. Offsets and DST are computed from the IANA time zone database.