Timezone transitions
List the UTC offset and abbreviation changes (daylight saving starts and ends) for the timezone at a point over a date range.
Signed in? Open this endpoint in the dashboard playground, which uses your organization automatically. Signed out, use Try in Playground below with your API key.
apiKey<token>Your API key from the dashboard, sent as ?apiKey=<key>.
lat*numberLatitude.
-90 <= value <= 90lon*numberLongitude.
-180 <= value <= 180from*stringRFC 3339 start instant (exclusive). Percent-encode a + offset as %2B; an unencoded + that arrives as a space is repaired.
Deviation (approximated): exclusive, and not limited to 2025-01-01 or later.
date-timeto*stringRFC 3339 end instant (inclusive). Must not be before from; at most 50 years after it.
Deviation (approximated): inclusive, and not limited to 2032-01-01 or earlier.
date-timeTransitions per covering timezone.
application/json- response
lat*numberEcho of the query lat.
lon*numberEcho of the query lon.
from*stringQuery from, normalised to UTC without fractional seconds.
date-timeto*stringQuery to, normalised to UTC without fractional seconds.
date-timetzdb_version*stringtzdb release the offsets and transitions come from.
timezones*array<>Every zone polygon covering the point (normally one; two where polygons overlap; empty over open ocean or outside the data).
curl -X GET 'https://api.data.graphitelab.ai/v1/timezone/transitions?lat=43.65&lon=-79.38&from=2027-01-01T00%3A00%3A00Z&to=2028-01-01T00%3A00%3A00Z'{ "lat": 43.65, "lon": -79.38, "from": "2027-01-01T00:00:00Z", "to": "2028-01-01T00:00:00Z", "tzdb_version": "2026f", "timezones": [ { "name": "America/Toronto", "transitions": [ { "at": "2027-03-14T07:00:00Z", "before": { "type": "standard", "utc_offset": "-05:00", "offset_seconds": -18000, "abbreviation": "EST" }, "after": { "type": "daylightSaving", "utc_offset": "-04:00", "offset_seconds": -14400, "abbreviation": "EDT" }, "offset_change_seconds": 3600, "kind": "daylight-start" }, { "at": "2027-11-07T06:00:00Z", "before": { "type": "daylightSaving", "utc_offset": "-04:00", "offset_seconds": -14400, "abbreviation": "EDT" }, "after": { "type": "standard", "utc_offset": "-05:00", "offset_seconds": -18000, "abbreviation": "EST" }, "offset_change_seconds": -3600, "kind": "daylight-end" } ] } ]}Full schema: API reference
Returns every offset or abbreviation change, such as a daylight saving start or end, for the timezone(s) covering a coordinate between from and to. Use it to schedule across a DST boundary or to know exactly when a zone's clocks change. For the current offset and the next change only, use the timezone endpoint. Endpoint: GET /v1/timezone/transitions.
How it works
-
A PostGIS point-in-polygon lookup (
ST_Covers) against the timezone-boundary-builder polygons (release 2026f) finds the IANA zone(s) atlat/lon. -
For each zone, the gateway scans the range one day at a time using the Node ICU tzdata, which is pinned to the same tzdb release. When the offset or abbreviation differs across a day, it bisects down to the exact second.
No routing or geocoding Engine is involved, and no external service is called. The response reports the tzdb release that ICU actually loaded as tzdb_version.
Quick start
curl -s "https://api.data.graphitelab.ai/v1/timezone/transitions?lat=43.65&lon=-79.38&from=2027-01-01T00:00:00Z&to=2028-01-01T00:00:00Z&apiKey=$GRAPHITE_API_KEY"{
"lat": 43.65,
"lon": -79.38,
"from": "2027-01-01T00:00:00Z",
"to": "2028-01-01T00:00:00Z",
"tzdb_version": "2026f",
"timezones": [
{
"name": "America/Toronto",
"transitions": [
{
"at": "2027-03-14T07:00:00Z",
"before": { "type": "standard", "utc_offset": "-05:00", "offset_seconds": -18000, "abbreviation": "EST" },
"after": { "type": "daylightSaving", "utc_offset": "-04:00", "offset_seconds": -14400, "abbreviation": "EDT" },
"offset_change_seconds": 3600,
"kind": "daylight-start"
},
{
"at": "2027-11-07T06:00:00Z",
"before": { "type": "daylightSaving", "utc_offset": "-04:00", "offset_seconds": -14400, "abbreviation": "EDT" },
"after": { "type": "standard", "utc_offset": "-05:00", "offset_seconds": -18000, "abbreviation": "EST" },
"offset_change_seconds": -3600,
"kind": "daylight-end"
}
]
}
]
}Parameters
| Name | Type | Required | What it does |
|---|---|---|---|
lat | number (-90 to 90) | yes | Latitude. |
lon | number (-180 to 180) | yes | Longitude. |
from | string, RFC 3339 date-time | yes | Start instant, exclusive. Percent-encode a + offset as %2B; an unencoded + that arrives as a space is repaired. |
to | string, RFC 3339 date-time | yes | End instant, inclusive. Must not be before from and at most 50 years after it. |
Response
| Field | Meaning |
|---|---|
lat, lon | Echo of the query. |
from, to | Query instants normalized to UTC without fractional seconds. |
tzdb_version | tzdb release the offsets and transitions come from (for example 2026f). |
timezones | One entry per zone polygon covering the point. Normally one; empty over open ocean or outside the data. |
timezones[].name | IANA zone name (the tzid). Its Place ID would be gp:tz:<tzid> (ADR 0006), but this endpoint returns only the name. |
timezones[].transitions | Changes in time order; empty when the zone has none in the range. |
at | UTC instant of the change, to the second. |
before, after | Offset state either side: type, utc_offset (+HH:MM), offset_seconds, abbreviation. |
offset_change_seconds | after.offset_seconds - before.offset_seconds; 0 for a pure abbreviation change. |
kind | daylight-start, daylight-end, offset-change or designation-change. |
type is standard when the offset equals the smaller of the zone's January and July offsets that year, daylightSaving when larger, and other when smaller. The abbreviation may be a GMT offset such as GMT-5 where tzdb has no abbreviation.
No place_id, datasource or rank is returned by this endpoint.
Differences from Geoapify
-
approximated: the interval is
(from, to]. A transition exactly atfromis not listed; one exactly attois. Geoapify uses[from, to). -
approximated: the maximum span is 50 years, and any date is accepted. Geoapify limits the span to 366 days within 2025-01-01 to 2032-01-01.
-
extra:
timezonescan hold zero or several zones (overlapping polygons), andatis rendered without fractional seconds. Offsets are computed for each zone name directly.
Nothing from Geoapify's parameter list is dropped.
US and Canada notes
Zones come from the full timezone-boundary-builder release, not from a US/Canada extract, so the lookup is not limited to the two countries. Both examples on this page are in the two countries: Toronto observes DST, and Indianapolis (America/Indiana/Indianapolis) is a distinct IANA zone that has the same 2027 transitions as the Eastern zone.
More examples
Indianapolis, calendar year 2027. Shows the Indiana zone name and the same DST pair of changes.
curl -s "https://api.data.graphitelab.ai/v1/timezone/transitions?lat=39.77&lon=-86.16&from=2027-01-01T00:00:00Z&to=2028-01-01T00:00:00Z&apiKey=$GRAPHITE_API_KEY"Errors and limits
| Status | When |
|---|---|
| 400 | Missing or invalid lat, lon, from or to; to before from; range over 50 years. |
| 401 | Missing or invalid apiKey. |
| 500 | Internal error. |
Limits: from and to must be RFC 3339 date-times, and to - from must not exceed 50 x 366 days.
Try in Playground (signed in to your Graphite Lab organization). Signed out, use the paste-your-key widget on the reference page.