Get the timezone from geo coordinates
License: MIT. Built with: Go, Makefile, Dockerfile. Source: https://github.com/noandrea/geo2tz.
that returns a JSON reply (`http/200`), for example: ```console curl -s http://localhost:2004/tz/51.477811/0 | jq ``` ```json { "coords": { "lat": 51.47781, "lon": 0 }, "tz": "Europe/London" } ``` or in case of errors (`http/4**`), for example: ```console curl -v http://localhost:2004/tz/51.477811/1000 | jq * Trying 127.0.0.1:2004... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to localhost (127.0.0.1) port 2004 (#0) > GET /tz/51.477811/1000 HTTP/1.1 > Host: localhost:2004 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 400 Bad Request < Content-Type: application/json; charset=UTF-8 < Vary: Origin < Date: Fri, 23 Jun 2023 19:09:29 GMT < Content-Length: 54 < { [54 bytes data] 100 54 100 54 0 0 89403 0 --:--:-- --:--:-- --:--:-- 54000 * Connection #0 to host localhost left intact ``` ```json { "message": "lon value 1000 out of range (-180/+180)" } ``` The version of the database is exposed at `/tz/version`: ```console curl -s http://localhost:2004/tz/version | jq ``` ```json { "version": "2024a", "url": "https://github.com/evansiroky/timezone-boundary-builder/releases/tag/2024a", "geo_data_url": "https://github.com/evansiroky/timezone-boundary-builder/releases/download/2024a/timezones-with-oceans.geojson.zip" } ``` ### Authorization Geo2Tz supports a basic token authorization mechanism, if the configuration value for `web.auth_token_value` is a non-empty string, geo2tz will check the query parameter value to authorize incoming requests. For example, running the service with: ```sh docker run --pull=always -p 2004:2004 -e GEO2TZ_WEB_AUTH_TOKEN_VALUE=secret ghcr.io/noandrea/geo2tz:latest ``` will enable authorization. With the authorization enabled, a query that does not specify the token will fail with an HTTP code 401: ```sh > curl -sv http://localhost:2004/tz/41.902782/12.496365 | jq ``` ``` * Trying 127.0.0.1:2004... * Connected to localhost (127.0.0.1) port 2004 (#0) > GET /tz/41.902782/12.496365 HTTP/1.1 > Host: localhost:2004 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 401 Unauthorized < Content-Type: application/json; charset=UTF-8 < Vary: Origin < Date: Sun, 31 Jul 2022 20:06:56 GMT < Content-Length: 27 < { [27 bytes data] * Connection #0 to host localhost left intact { "message": "unauthorized" } ``` Passing the token in the query parameters will succeed instead: ```sh > curl -s http://localhost:2004/tz/41.902782/12.496365\?t\=secret | jq ``` ```json { "coords": { "lat": 41.902782, "lon": 12.496365 }, "tz": "Europe/Rome" } ``` ## Docker Docker image is available at [geo2tz](https://github.com/noandrea/geo2tz/pkgs/container/geo2tz) ```sh docker run --pull=always -p 2004:2004 ghcr.io/noandrea/geo2tz:latest ``` The image is built on [scratch](https://hub.docker.com/_/scratch): ## Docker compose Docker compose YAML example ```yaml version: '3' services: geo2tz: container_name: geo2tz image: ghcr.io/noandrea/geo2tz:latest ports: - 2004:2004 # uncomment to enable authorization via request token # environment: # - GEO2TZ_WEB_AUTH_TOKEN_VALUE=somerandomstringhere # - GEO2TZ_WEB_AUTH_TOKEN_PARAM_NAME=t # - GEO2TZ_WEB_LISTEN_ADDRESS=":2004"
Self-hosting gives you three things SaaS can’t: data ownership (the files live on disks you control), cost predictability (a one-time setup vs. recurring per-seat fees that grow with your household or team), and longevity (open-source means the app keeps working even if the maintainers move on, since you can pin a working version). The trade-off is that you take on the operational work of running a server, applying updates, and handling backups.
Most self-hosted apps run comfortably on modest hardware — a Raspberry Pi 4, a mini PC, a NAS with Docker support, or a small VPS is usually enough for personal or family use. CPU and RAM requirements scale with how many simultaneous users or how much data you push through Geo2tz. Storage requirements depend on the kind of data you keep; check the README for guidance on data retention.
Last verified: 2026-05-21