Alternatives

Alternative python packages

  • tzfpy (less accurate, more lightweight, faster)

  • pytzwhere (not maintained)

Comparison to tzfpy

tzfpy is a Python binding of the Rust package tzf-rs, which serves as an alternative to timezonefinder with different trade-offs.

Both packages use the full original dataset (>440 timezones), providing full localization capabilities and historical timezone accuracy.

Important: timezonefinder maintains higher accuracy around timezone borders because it uses complete, non-simplified polygon data. In contrast, tzfpy uses simplified polygons for performance, which can lead to inaccuracies near boundaries.

Both packages will likely coexist as they serve different use cases:

Comprehensive Comparison:

Feature

timezonefinder

tzfpy

Implementation

Pure Python with optional C extensions and Numba compilation

Python binding of Rust package tzf-rs

Dataset Version

Full original dataset (>440 timezones)

Full original dataset (>440 timezones)

Startup Time

Requires initialization time

No startup time (immediate)

Avg. Lookup Speed Queries per Second

>500k in a single CPU of a new Macbook Pro M5 ults_timezonefinding`

~320k

Data Representation

Complete, non-simplified timezone polygons

Simplified timezone polygons

Border Accuracy

Higher accuracy around timezone borders (full polygon precision)

Lower accuracy near borders due to simplified polygons

Distribution Size

~28 MB

~6 MB

Memory Usage

TBA

TBA

Spatial Index

H3 hexagon-based index with ~41k cells (resolution 3)

Hierarchical tree of ~80k rectangles with fallback to simplified polygon data

Build Complexity

Easier to build when wheels are missing

Requires Rust to build wheels for some platforms

Python Compatibility

Better compatibility across Python versions

Requires Rust to build wheels on certain platforms or Python versions

Additional Features

get_geometry() for retrieving the timezone shapes

Return GeoJSON representation of timezone shapes and timezone’s indexes

Maintainability

Single repository

Downstream of multiple repositories (tzf, tzf-rel, tzf-rs) languages (Go, Rust, Python)

When to Choose Which Package:

Use Case

Recommended Package

Timezone border accuracy

timezonefinder

Access to timezone geometry data

Either

Compatibility with varied Python environments

timezonefinder

Maintainability and Ease of Contribution

timezonefinder

Lookup Performance

tzfpy

Initialization Time

tzfpy

Minimal Distribution Size

tzfpy

Full localization power (>440 timezone names)

Either

Memory efficiency

Either

Comparison to pytzwhere

This project has originally been derived from pytzwhere (github), but aims at providing improved performance and usability.

pytzwhere is parsing a 76MB .csv file (floats stored as strings!) completely into memory and computing shortcuts from this data on every startup. This is time, memory and CPU consuming. Additionally calculating with floats is slow, keeping those 4M+ floats in the RAM all the time is unnecessary and the precision of floats is not even needed in this case (s. detailed comparison and speed tests below).

In comparison most notably initialisation time and memory usage are significantly reduced. pytzwhere is using up to 450MB of RAM (with shapely and numpy active), because it is parsing and keeping all the timezone polygons in the memory. This uses unnecessary time/ computation/ memory and this was the reason I created this package in the first place. This package uses at most 40MB (= encountered memory consumption of the python process) and has some more advantages:

Differences:

  • highly decreased memory usage

  • highly reduced start up time

  • usage of 32bit int (instead of 64+bit float) reduces computing time and memory consumption. The accuracy of 32bit int is still high enough. According to my calculations the worst accuracy is 1cm at the equator. This is far more precise than the discrete polygons in the data.

  • the data is stored in memory friendly binary files (approx. 41MB in total, original data 120MB .json)

  • data is only being read on demand (not completely read into memory if not needed)

  • precomputed shortcuts are included to quickly look up which polygons have to be checked

  • function get_geometry() enables querying timezones for their geometric shape (= multipolygon with holes)

  • further speedup possible by the use of numba (code JIT compilation)

  • tz_where is still using the outdated tz_world data set