timezonefinder Documentation

repository·master·Indexed 19 days ago

https://github.com/jannikmi/timezonefinder

A Python package for finding the timezone of any point on earth (WGS84 coordinates) offline. It provides high-accuracy lookups using point-in-polygon tests and includes optimizations via a C extension or Numba JIT compilation. The library offers both a standard TimezoneFinder class and a lightweight TimezoneFinderL version, along with a CLI for quick lookups.

Tokens
10.6K
Snippets
42
Records
57
Agent score
67%

What's inside timezonefinder

  1. What is timezonefinder

    master

    timezonefinder is a Python package used to look up the corresponding timezone for given latitude/longitude coordinates on Earth. The package works entirely offline.

    Internally, timezones are represented as polygons. The membership of a specific point (lat/lng pair) is determined using a Point in Polygon (PIP) check. The library includes optimizations to avoid expensive PIP checks whenever possible.

  2. Understand the timezonefinder data format and structure

    master

    The timezonefinder library uses highly optimized binary data structures to enable fast and memory-efficient timezone lookups. The data is organized into several specialized files:

    • Polygon Coordinates: Stored in FlatBuffers binary files (coordinates.fbs) for boundary polygons and holes.
    • Hybrid Shortcut Index: A spatial index using H3 hexagons (hybrid_shortcuts_uint8.fbs or hybrid_shortcuts_uint16.fbs) that stores either direct zone IDs or lists of polygon IDs.
    • Numpy Arrays: .npy files storing polygon information, such as zone_ids.npy, zone_positions.npy, and bounding boxes (xmin.npy, xmax.npy, ymin.npy, ymax.npy).
    • Zone Names: A timezone_names.txt file listing all timezone names.
    • Hole Registry: A mapping from polygon IDs to the amount and position of its holes.
  3. Use TimezoneFinderL for lightweight proximity lookups

    master

    The TimezoneFinderL class is a lightweight version of TimezoneFinder. Instead of using polygon data, it uses only precomputed "shortcuts" to instantly suggest the most probable timezone. This is ideal for resource-constrained environments or when high-speed proximity suggestions are sufficient.

    Optimization Tip: If you only use TimezoneFinderL, you can delete the data/boundaries and data/holes folders to create a very small installation (a few MB).

    from timezonefinder import TimezoneFinderL
    
    tf = TimezoneFinderL(in_memory=True)
    
    tz = tf.timezone_at(lng=13.358, lat=52.5061)  # 'Europe/Paris'
    
    # Or for certain results via shortcuts
    tz_unique = tf.unique_timezone_at(lng=13.358, lat=52.5061)
  4. Compare timezonefinder with pytzwhere

    master

    While timezonefinder was originally derived from pytzwhere, it is designed to be a significantly more efficient alternative. pytzwhere is largely unmaintained and suffers from high resource consumption.

    Advantages of timezonefinder over pytzwhere

    • Memory Usage: timezonefinder uses at most ~40MB of RAM, whereas pytzwhere can use up to 450MB because it parses and keeps all polygons in memory.
    • Startup Time: timezonefinder has highly reduced startup time compared to pytzwhere, which must parse a 76MB CSV file and compute shortcuts on every startup.
    • Data Efficiency: timezonefinder uses memory-friendly binary files and reads data on demand. It also uses 32-bit integers instead of 64-bit floats, which reduces computation time and memory without sacrificing necessary precision.
    • Dataset: timezonefinder uses modern data, whereas pytzwhere uses the outdated tz_world dataset.
  5. Compare timezonefinder with tzfpy

    master

    When choosing between timezonefinder and tzfpy, consider your requirements for accuracy versus performance. Both packages use the full original dataset (>440 timezones) and provide full localization and historical accuracy.

    Key Differences

    Featuretimezonefindertzfpy
    Border AccuracyHigher (uses complete, non-simplified polygons)Lower (uses simplified polygons for speed)
    ImplementationPure Python (optional C extensions/Numba)Python binding of Rust (tzf-rs)
    Startup TimeRequires initialization timeImmediate (no startup time)
    Lookup Speed>500k queries/sec (on high-end hardware)~320k queries/sec
    Distribution Size~28 MB~6 MB
    Spatial IndexH3 hexagon-based indexHierarchical tree of rectangles
    Build ComplexityEasier (standard Python)Requires Rust to build wheels on some platforms

    Decision Guide

    • Choose timezonefinder if: You need high accuracy around timezone borders, need to access timezone geometry via get_geometry(), or require high compatibility across varied Python environments.
    • Choose tzfpy if: You prioritize lookup performance, minimal distribution size, or zero startup/initialization time.
  6. How spatial indexing with H3 hexagons works

    master

    The library uses Uber's H3 library to divide the Earth's surface into a grid of hexagons (using resolution 3, totaling ~41k hexagons). This acts as a spatial index to drastically reduce the number of polygons that need to be checked during a lookup.

    The Hybrid Storage Approach

    For each hexagon cell, the library uses one of two storage methods:

    1. Unique zones: If all polygons in a hexagon belong to the same timezone, the zone ID is stored directly. This allows for immediate results without polygon testing.
    2. Multiple zones: If a hexagon contains polygons from different timezones, an array of polygon IDs is stored. The library then only tests those specific polygons to find the match.

    This approach balances precision, memory efficiency, and lookup speed.

  7. Install timezonefinder via pip

    master

    You can install the base package using pip. For improved performance, it is recommended to install the optional numba dependency. If your project also uses pytz, you should install the pytz extra to ensure compatibility and avoid issues with updated timezone names.

    # Standard installation
    pip install timezonefinder
    
    # Installation with numba for improved speed
    pip install timezonefinder[numba]
    
    # Installation with pytz support to avoid incompatibilities
    pip install timezonefinder[pytz]
  8. Use global functions for simple timezone lookups

    master

    For single-threaded, simple use cases, timezonefinder provides global functions that use a thread-safe singleton instance. Note that the first call will be slower due to lazy initialization.

    Warning: While the singleton initialization is thread-safe, the shared instance itself is NOT safe for concurrent reads. For parallel workloads (threading, asyncio, multiprocessing), you must create separate TimezoneFinder instances for each thread/process.

    from timezonefinder import timezone_at
    
    tz = timezone_at(lng=13.358, lat=52.5061)  # 'Europe/Paris'
  9. Use Numba for JIT compilation

    master

    You can significantly increase performance by installing the optional numba dependency. This allows utility functions to be JIT compiled.

    Note on priority: If Numba is available, the JIT-compiled Python version of the point-in-polygon algorithm will be used instead of the C extension, as it is even faster.

    It is highly recommended to install numba if a C compiler was not available during the initial build process.

    To install with Numba support:

    pip install timezonefinder[numba]

    To check if Numba is being used:

    TimezoneFinder.using_numba()  # returns True or False
  10. Optimize performance with the C extension

    master

    During installation, timezonefinder attempts to compile a C extension to implement the time-critical point-in-polygon check algorithm. This requires a Clang compiler to be installed on your system.

    If compilation fails (e.g., due to a missing C compiler or broken cffi installation), the library silently falls back to a pure Python implementation, which is approximately 400x slower.

    You can verify if the compiled C implementation is active using TimezoneFinder.using_clang_pip().

    # Returns True if the compiled C implementation is being used
    TimezoneFinder.using_clang_pip()
  11. Choose between standard and reduced datasets

    master

    When building or processing data for timezonefinder, you can choose between the standard dataset and a reduced version.

    Standard Dataset (timezones-with-oceans)

    • Content: Includes boundaries with ocean time zones and the full original dataset.
    • Pros: High precision, includes location-specific information (e.g., Europe/Berlin), and supports historical timekeeping methods.
    • Cons: Larger memory footprint.

    Reduced Dataset (timezones-now)

    • Content: Merges timezones with identical behavior (as of now) into a single zone.
    • Pros: Significantly smaller memory footprint (reduces ~440 timezones to ~90).
    • Cons:
      • Provides incorrect data for historical timekeeping.
      • Loses location-specific information (e.g., Europe/Berlin might become Europe/Paris).
      • Reduces localization capabilities.

    To use the reduced dataset, use the update_data.sh script with the --dataset=same-since-now flag.