Time zone at a place
The IANA time zone at a latitude and longitude, offline, and the local time and UTC offset there, summer time counted.
Version 1.0.0 · 3 functions · 3 crates
Functions
What use timezone_at.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use timezone_at, timezone_all_at from timezone_at (Quillo 0.6).
timezone_at(lat: float, lon: float) → stror an errorThe time zone's name at a point, such as "America/New_York". At sea it is an Etc/GMT±n zone.
timezone_all_at(lat: float, lon: float) → listor an errorEvery zone that claims a point: more than one only where borders are disputed.
timezone_local(lat: float, lon: float, at: int) → anyor an errorWhat time it is at a point, or at the Unix time at (seconds; 0 for now): { zone, local, offset, offset_minutes, abbreviation }, local as 2026-10-29T14:05:00, offset as +01:00, summer time counted.
Get it
$ quillo install timezone_at # timezone_at.qwer into this folder$ quillo install timezone_at --example # and its example, timezone_at.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/timezone_at.qwer$ curl -O https://quillolang.org/plugins/files/timezone_at.qweThen, in your program, all of it or only what you call:
use timezone_at.qweruse timezone_at, timezone_all_at from timezone_at // Quillo 0.6: only theseIt uses these crates, which cargo fetches the first time the plugin is built:
tzf-rs = "0.4"chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }chrono-tz = "0.10"Example
// Delivery slots shown in the customer's own time: the time zone of an address's coordinates,// and what time it is there.//// quillo run timezone_at.qwe then open http://localhost:8080/zone?lat=40.71&lon=-74.0use "timezone_at.qwer"route GET /zone ? { lat: float, lon: float } { let here = timezone_local(lat, lon, 0)? { zone: here.zone, offset: here.offset, now_there: here.local }}// 1 July 2026 12:00 UTC at four warehouses: summer time shows in the offsets.route GET /warehouses = [ { city: "Amsterdam", lat: 52.37, lon: 4.89 }, { city: "Sydney", lat: -33.87, lon: 151.21 }, { city: "Phoenix", lat: 33.45, lon: -112.07 }, { city: "Kathmandu", lat: 27.7, lon: 85.32 },] | map((w) => { let t = timezone_local(w.lat, w.lon, 1782907200)?; { city: w.city, zone: t.zone, local: t.local, abbreviation: t.abbreviation } })route GET /sea = { atlantic: timezone_at(30.0, -40.0)?, bad: timezone_at(95.0, 0.0).error }$ quillo run timezone_at.qwe$ curl 'localhost:8080/zone?lat=40.71&lon=-74.0'$ curl 'localhost:8080/warehouses'$ curl 'localhost:8080/sea'Source
//! The IANA time zone at a latitude and longitude, offline (no API key, no network): "Europe/Amsterdam" for a delivery address or a photo's GPS, and the local time and UTC offset there.//! version: 1.0.0//!//! [dependencies]//! tzf-rs = "0.4"//! chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }//! chrono-tz = "0.10"use chrono::{Offset, TimeZone, Utc};use serde_json::{json, Value};use std::sync::OnceLock;/// The zone finder, built once (its data is in the library; the first call takes a moment).fn finder() -> &'static tzf_rs::DefaultFinder { static F: OnceLock<tzf_rs::DefaultFinder> = OnceLock::new(); F.get_or_init(tzf_rs::DefaultFinder::new)}fn check(lat: f64, lon: f64) -> Result<(), String> { if !(-90.0..=90.0).contains(&lat) || !(-180.0..=180.0).contains(&lon) { return Err(format!("{}, {} is not a place: latitude is -90 to 90, longitude -180 to 180", lat, lon)); } Ok(())}/// The time zone's name at a point, such as "America/New_York". At sea it is an `Etc/GMT±n` zone.pub fn timezone_at(lat: f64, lon: f64) -> Result<String, String> { check(lat, lon)?; Ok(finder().get_tz_name(lon, lat).to_string())}/// Every zone that claims a point: more than one only where borders are disputed.pub fn timezone_all_at(lat: f64, lon: f64) -> Result<Vec<String>, String> { check(lat, lon)?; Ok(finder().get_tz_names(lon, lat).into_iter().map(str::to_string).collect())}/// What time it is at a point, or at the Unix time `at` (seconds; 0 for now): `{ zone, local, offset, offset_minutes, abbreviation }`,/// `local` as `2026-10-29T14:05:00`, `offset` as `+01:00`, summer time counted.pub fn timezone_local(lat: f64, lon: f64, at: i64) -> Result<Value, String> { check(lat, lon)?; let name = finder().get_tz_name(lon, lat); let tz: chrono_tz::Tz = name.parse().map_err(|_| format!("{} is not a zone this library knows", name))?; let when = if at == 0 { Utc::now() } else { Utc.timestamp_opt(at, 0).single().ok_or(format!("{} is not a time", at))? }; let local = when.with_timezone(&tz); let secs = local.offset().fix().local_minus_utc(); Ok(json!({ "zone": name, "local": local.format("%Y-%m-%dT%H:%M:%S").to_string(), "offset": local.format("%:z").to_string(), "offset_minutes": secs / 60, "abbreviation": local.format("%Z").to_string(), }))}Related
coordinates.qwer · 1.0.0Coordinates as people write them, such as 52°22'N 4°53'E or N 52° 22.2', read as one, written as degrees-minutes-seconds, and converted to and from UTM.7 views · 8 downloadsH3 hexagons h3.qwer · 1.0.0H3 hexagon cells: the cell of a point at a resolution, its neighbours within k rings, its outline for a map, and distances between cells.7 views · 8 downloadsKML and KMZ kml.qwer · 1.0.0KML and KMZ files from Google Earth and My Maps read to GeoJSON, placemarks with their names, descriptions, folders and extended data, and GeoJSON written back as KML or KMZ.7 views · 8 downloadsMaidenhead locators maidenhead.qwer · 1.0.0Maidenhead grid locators as radio amateurs use them (FN31pr, JN58td): from a latitude and longitude at 2 to 10 characters, back to the square's centre and corners, and the distance and bearing between two.7 views · 8 downloadsMap clusters map_clusters.qwer · 1.0.0Map markers clustered by zoom as Supercluster does: thousands of points loaded once, then for each view and zoom the clusters with their counts and the single points, a cluster's points, and the zoom where it opens.7 views · 7 downloadsMap projections projections.qwer · 1.0.0Coordinates moved between map projections offline, by EPSG code or PROJ string: GPS degrees to Web Mercator, UTM, the British, Dutch and Swiss grids and some 6,000 others, for points and whole GeoJSON.8 views · 9 downloadsThread 0 posts
On Time zone at a place: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.