{"id":7830,"library":"tzwhere","title":"tzwhere","description":"tzwhere (also referred to as pytzwhere) is a Python library designed to look up the timezone for a given latitude and longitude entirely offline. The current version, 3.0.3, released in August 2017, focuses on improving how it handles 'holes' within timezone polygons. It is a mature library, but its data sources and development are not as current as some alternatives.","status":"maintenance","version":"3.0.3","language":"en","source_language":"en","source_url":"https://github.com/pegler/pytzwhere","tags":["timezone","geolocation","offline","latitude","longitude","pytzwhere"],"install":[{"cmd":"pip install tzwhere","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Optional dependency for performance improvements.","package":"numpy","optional":true},{"reason":"Required for geometric operations on timezone polygons.","package":"shapely","optional":false}],"imports":[{"note":"The module and the main class share the same name. Importing the module directly and then attempting to instantiate 'tzwhere()' will result in an AttributeError, as the module itself is not callable.","wrong":"import tzwhere","symbol":"tzwhere","correct":"from tzwhere import tzwhere"}],"quickstart":{"code":"from tzwhere import tzwhere\n\n# Initialize the tzwhere object (loads data into memory)\ntz = tzwhere.tzwhere()\n\n# Look up timezone for specific coordinates (e.g., Chicago)\nlatitude = 35.29\nlongitude = -89.66\ntz_name = tz.tzNameAt(latitude, longitude)\nprint(f\"Timezone at ({latitude}, {longitude}): {tz_name}\")\n\n# Example with a point outside a strict boundary, using forceTZ\nlatitude_ocean = 53.68\nlongitude_ocean = -6.24 # Near Dublin, Ireland, possibly in water\ntz_name_forced = tz.tzNameAt(latitude_ocean, longitude_ocean, forceTZ=True)\nprint(f\"Timezone (forced) at ({latitude_ocean}, {longitude_ocean}): {tz_name_forced}\")","lang":"python","description":"Initialize the tzwhere object once to load timezone data. Then, use the `tzNameAt` method with latitude and longitude to find the corresponding IANA timezone name. The `forceTZ=True` parameter can be used to find the closest timezone even if the point falls outside strict polygon boundaries."},"warnings":[{"fix":"Ensure you are importing the `tzwhere` class explicitly and instantiating it with `tz = tzwhere.tzwhere()` as documented in the quickstart.","message":"Version 2.0 introduced changes to the initialization function. Previous versions might have allowed direct instantiation or different parameters.","severity":"breaking","affected_versions":"2.0.x and later"},{"fix":"To get the closest timezone name in such cases, use the `forceTZ=True` parameter: `tz.tzNameAt(latitude, longitude, forceTZ=True)`.","message":"The `tzNameAt` method can return `None` if the given coordinates fall into 'holes' in the timezone data (e.g., small islands, open water, or points slightly outside polygon boundaries).","severity":"gotcha","affected_versions":"All versions"},{"fix":"For applications with strict memory or startup performance requirements, consider alternative libraries like `timezonefinder` which are optimized for speed and memory usage, or `geodjango-tzwhere` if using a spatial database.","message":"tzwhere loads all timezone boundary data into memory upon initialization, leading to significant memory consumption (around 60-250MB) and potentially slow startup times for applications.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For the most up-to-date and accurate timezone data, it is recommended to use actively maintained alternatives like `timezonefinder` which regularly updates its data.","message":"The underlying timezone data (VMAP0) used by tzwhere is based on older sources (e.g., basemap updated 2015 for v2.3.1, PyPI 3.0.3 from 2017) and is not actively maintained. This may lead to inaccuracies for more recent timezone boundary changes.","severity":"deprecated","affected_versions":"All versions, especially 3.0.x"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Change your import statement to `from tzwhere import tzwhere`. Then you can correctly instantiate the class with `tz = tzwhere()`.","cause":"You've imported the `tzwhere` module directly (`import tzwhere`) and then tried to call `tzwhere()` on the module object itself. The `tzwhere` class, which needs to be instantiated, is nested within the module that shares its name.","error":"AttributeError: 'module' object has no attribute 'tzwhere'"},{"fix":"Pass the `forceTZ=True` argument to the `tzNameAt` method to find the closest timezone even if the point is not strictly within a polygon: `tz.tzNameAt(latitude, longitude, forceTZ=True)`.","cause":"The provided latitude and longitude coordinates fall outside the strict boundaries of a defined timezone polygon or into a region not covered by the underlying VMAP0 data (e.g., open ocean, or small gaps).","error":"tz.tzNameAt(lat, lng) returns None unexpectedly."},{"fix":"If high memory usage or slow startup is a critical concern, consider migrating to alternative libraries like `timezonefinder` which offers optimizations for memory and speed, or `geodjango-tzwhere` for database-backed lookups.","cause":"The `tzwhere.tzwhere()` constructor loads all timezone geographical data into your application's memory. This dataset is large and can consume significant RAM, leading to slow initialization, especially on resource-constrained systems.","error":"MemoryError or application startup is very slow when initializing tzwhere."}]}