Quick Start
Project tzf provides multiple languages supports to lookup timezone by longitude and latitude.
| Language or Sever | Repository Link | API Doc | 
|---|---|---|
| Go | ringsaturn/tzf | |
| Ruby | HarlemSquirrel/tzf-rb | |
| Rust | ringsaturn/tzf-rs | |
| Swift | ringsaturn/tzf-swift | |
| Python | ringsaturn/tzfpy | tzfpy.pyi | 
| HTTP API | racemap/rust-tz-service | |
| Redis Server | ringsaturn/tzf-server | |
| JS via Wasm(browser only) | ringsaturn/tzf-wasm | |
| Online | ringsaturn/tzf-web | 
Go
1go get github.com/ringsaturn/tzf 1// Use about 150MB memory for init, and 60MB after GC.
 2package main
 3
 4import (
 5	"fmt"
 6
 7	"github.com/ringsaturn/tzf"
 8)
 9
10func main() {
11	finder, err := tzf.NewDefaultFinder()
12	if err != nil {
13		panic(err)
14	}
15	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
16}Full precise support
 1// Use about 900MB memory for init, and 660MB after GC.
 2package main
 3
 4import (
 5	"fmt"
 6
 7	"github.com/ringsaturn/tzf"
 8	tzfrel "github.com/ringsaturn/tzf-rel"
 9	pb "github.com/ringsaturn/tzf/gen/go/tzf/v1"
10	"google.golang.org/protobuf/proto"
11)
12
13func main() {
14	input := &pb.Timezones{}
15
16	// Full data, about 83.5MB
17	dataFile := tzfrel.FullData
18
19	if err := proto.Unmarshal(dataFile, input); err != nil {
20		panic(err)
21	}
22	finder, _ := tzf.NewFinderFromPB(input)
23	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
24}Rust
1cargo add tzf-rs 1use lazy_static::lazy_static;
 2use tzf_rs::DefaultFinder;
 3
 4lazy_static! {
 5    static ref FINDER: DefaultFinder = DefaultFinder::new();
 6}
 7
 8fn main() {
 9    // Please note coords are lng-lat.
10    print!("{:?}\n", FINDER.get_tz_name(116.3883, 39.9289));
11    print!("{:?}\n", FINDER.get_tz_names(116.3883, 39.9289));
12}Full precise support
By default, tzf-rs uses a simplified shape data. If you need 100% accurate lookup, you can use the following code to setup.
- Download full data set, about 90MB.
- Use the following code to setup.
 1use tzf_rs::Finder;
 2use tzf_rs::gen::tzf::v1::Timezones;
 3
 4pub fn load_full() -> Vec<u8> {
 5    include_bytes!("./combined-with-oceans.bin").to_vec()
 6}
 7
 8fn main() {
 9    println!("Hello, world!");
10    let file_bytes: Vec<u8> = load_full();
11
12    let finder = Finder::from_pb(Timezones::try_from(file_bytes).unwrap_or_default());
13    let tz_name = finder.get_tz_name(139.767125, 35.681236);
14    println!("tz_name: {}", tz_name);
15}A full example can be found here.
Python
 1# Install just tzfpy
 2pip install tzfpy
 3
 4# Install with pytz
 5pip install "tzfpy[pytz]"
 6
 7# Install with tzdata. https://github.com/python/tzdata
 8pip install "tzfpy[tzdata]"
 9
10# Install via conda, see more in https://github.com/conda-forge/tzfpy-feedstock
11conda install -c conda-forge tzfpy1>>> from tzfpy import get_tz, get_tzs
2>>> get_tz(116.3883, 39.9289)  # in (longitude, latitude) order.
3'Asia/Shanghai'
4>>> get_tzs(87.4160, 44.0400)  # in (longitude, latitude) order.
5['Asia/Shanghai', 'Asia/Urumqi']Python version does not support full precise support.
Wasm
 1<!DOCTYPE html>
 2<html lang="en">
 3  <head>
 4    <meta charset="UTF-8" />
 5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6    <title>tzf-web Example</title>
 7    <script type="module">
 8      import init, { WasmFinder } from "https://www.unpkg.com/tzf-wasm@v0.1.4/tzf_wasm.js";
 9
10      let finder;
11
12      async function loadWasm() {
13        await init();
14        finder = new WasmFinder();
15        const lng = -74.006;
16        const lat = 40.7128;
17        const timezone = finder.get_tz_name(lng, lat);
18        console.log(`Timezone for (${lat}, ${lng}): ${timezone}`);
19      }
20
21      loadWasm();
22    </script>
23  </head>
24  <body></body>
25</html>Online preview: http://ringsaturn.github.io/tzf-web/
Swift
Add the dependency to your Package.swift file:
1dependencies: [
2    .package(url: "https://github.com/ringsaturn/tzf-swift.git", from: "{latest_version}")
3] 1import Foundation
 2import tzf
 3
 4do {
 5    let finder = try DefaultFinder()
 6
 7    // Test for Beijing
 8    let timezone = try finder.getTimezone(lng: 116.3833, lat: 39.9167)
 9    print("Beijing timezone:", timezone)
10
11    // Test for a location with multiple possible timezones
12    let timezones = try finder.getTimezones(lng: 87.5703, lat: 43.8146)
13    print("Multiple possible timezones:", timezones)
14
15    // Get data version
16    print("Data version:", finder.dataVersion())
17
18} catch {
19    print("Error:", error)
20}Ruby
Ruby version is created and maintained by HarlemSquirrel.
Detailed documentation can be found in it’s repo tzf-rb.
1bundle add tzf
2# or
3gem install tzf1# https://github.com/HarlemSquirrel/tzf-rb
2require 'tzf'
3
4TZF.tz_name(40.74771675713742, -73.99350390136448)
5# => "America/New_York"
6
7TZF.tz_names(40.74771675713742, -73.99350390136448)
8# => ["America/New_York"]CLI
There are 2 CLI implementations for project-tzf, one is based on Go, the other is based on Rust.
tzf’s CLI
1go install github.com/ringsaturn/tzf/cmd/tzf@latestThen:
1tzf -lng 116.3883 -lat 39.9289Or batch process:
1echo -e "116.3883 39.9289\n116.3883, 39.9289" | tzf -stdin-order lng-lattzf-rs’s CLI
1cargo install tzf-rsThen:
1tzf --lng 116.3883 --lat 39.9289Or batch process:
1echo -e "116.3883 39.9289\n116.3883, 39.9289" | tzf --stdin-order lng-latIf you are using NixOS, you can install tzf-rs’s CLI via Nix, please see NixOS for more details, since it’s maintained by community.