tzf-rs

Crates.iotzf-rs
lib.rstzf-rs
version
sourcesrc
created_at2022-11-20 14:58:10.276548+00
updated_at2025-02-21 11:09:06.60137+00
descriptionFast convert longitude,latitude to timezone name.
homepagehttps://github.com/ringsaturn/tzf-rs
repositoryhttps://github.com/ringsaturn/tzf-rs
max_upload_size
id719158
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
ringsaturn (ringsaturn)

documentation

https://docs.rs/tzf-rs

README

tzf-rs: a fast timezone finder for Rust. Rust Documentation

Time zone map of the world

[!NOTE]

This package uses simplified shape data so it is not entirely accurate around the border.

Build options

By default, the binary is built as well. If you don't want/need it, you can omit the default features and build like this:

cargo build --no-default-features

Or add in the below way:

cargo add tzf-rs --no-default-features

Best Practices

It's expensive to init tzf-rs's Finder/FuzzyFinder/DefaultFinder, so please consider reusing instances or creating one as a global variable. Below is a global variable example:

use lazy_static::lazy_static;
use tzf_rs::DefaultFinder;

lazy_static! {
    static ref FINDER: DefaultFinder = DefaultFinder::new();
}

fn main() {
    print!("{:?}\n", FINDER.get_tz_name(116.3883, 39.9289));
    print!("{:?}\n", FINDER.get_tz_names(116.3883, 39.9289));
}

For reuse, racemap/rust-tz-service provides a good example.

A Redis protocol demo could be used here: ringsaturn/redizone.

Performance

The tzf-rs package is intended for high-performance geospatial query services, such as weather forecasting APIs. Most queries can be returned within a very short time, averaging around 3,000 nanoseconds (about 1,000ns slower than with Go repo tzf. I will continue improving this - you can track progress here).

Here is what has been done to improve performance:

  1. Using pre-indexing to handle most queries takes approximately 1000 nanoseconds.
  2. Using a finely-tuned Ray Casting algorithm package ringsaturn/geometry-rs to verify whether a polygon contains a point.

That's all. There are no black magic tricks inside the tzf-rs.

Below is a benchmark run on global cities(about 14K), and avg time is about 3,000 ns per query:

// require toolchain.channel=nightly 

#![feature(test)]
#[cfg(test)]
mod benches_default {

    use tzf_rs::DefaultFinder;
    extern crate test;
    use test::Bencher;
    #[bench]
    fn bench_default_finder_random_city(b: &mut Bencher) {
        let finder: DefaultFinder = DefaultFinder::default();

        b.iter(|| {
            let city = cities_json::get_random_cities();
            let _ = finder.get_tz_name(city.lng, city.lat);
        });
    }
}
test benches_default::bench_default_finder_random_city ... bench:       1,220.19 ns/iter (+/- 54.36)
Criterion result Pic
PDF
Regression

You can view more details from latest benchmark from GitHub Actions logs.

References

I have written an article about the history of tzf, its Rust port, and its Rust port's Python binding; you can view it here.

Bindings

Command line

The binary helps in debugging tzf-rs and using it in (scripting) languages without bindings. Either specify the coordinates as parameters to get a single time zone, or to look up multiple coordinates efficiently specify the ordering and pipe them to the binary one pair of coordinates per line.

tzf --lng 116.3883 --lat 39.9289
echo -e "116.3883 39.9289\n116.3883, 39.9289" | tzf --stdin-order lng-lat

LICENSE

This project is licensed under the MIT license. The data is licensed under the ODbL license, same as evansiroky/timezone-boundary-builder

Commit count: 235

cargo fmt