A high-performance Python library for parsing and analyzing the IANA Time Zone Database (tzdb). Built for production use with smart caching, minimal dependencies, and a practical API.
- 🚀 Blazing Fast: Smart caching system for instant subsequent loads
- 📦 Zero Dependencies: Pure Python standard library
- 🏗️ Production Ready: Robust error handling and validation
- 🔍 Comprehensive: Full coverage of TZDB files and formats
- 📊 Multiple Outputs: JSON, dictionaries, pandas DataFrames
- 🌍 Geographic Data: Timezone coordinates and country mappings
- ⏰ Transition Analysis: DST and offset change calculations
pip install x-zic
Or clone from source:
git clone https://github.com/mlotfic/x-zic
cd x-zic
pip install -e .
from x_zic import read_zones, get_transitions
# Read all timezones (automatically caches for future calls)
zones = read_zones()
print(f"Found {len(zones)} timezones")
# Get DST transitions for New York
transitions = get_transitions('America/New_York', 2020, 2025)
for transition in transitions[:3]: # Show first 3
print(f"{transition['timestamp']}: {transition['abbrev']} ({transition['offset_after']})")
import x_zic
# Read all zones
all_zones = x_zic.read_zones()
# Read by region
european_zones = x_zic.read_zones('europe')
asian_zones = x_zic.read_zones('asia')
# Parse specific files
from x_zic.parser import parse_zone, parse_rule
zones = parse_zone('northamerica', loader)
rules = parse_rule('europe', loader)
# Get DST transitions
transitions = x_zic.get_transitions(
'America/Los_Angeles',
start_year=2020,
end_year=2025
)
# Analyze transition patterns
for t in transitions:
print(f"{t['timestamp']} | {t['abbrev']:>4} | "
f"{t['offset_before']} → {t['offset_after']} | "
f"DST: {t['is_dst']}")
from x_zic.geo import read_zonetab
# Get timezones with coordinates
geo_zones = read_zonetab()
for zone in geo_zones[:5]:
print(f"{zone['zone_id']} | {zone['country_code']} | "
f"({zone['latitude']}, {zone['longitude']})")
from x_zic.core.config import TZDBConfig
from x_zic.core.loader import FileLoader
# Custom setup
config = TZDBConfig(
tzdb_source_path="/path/to/tzdb-2025b",
cache_dir="/tmp/tzdb_cache",
max_transition_years=50
)
loader = FileLoader(config)
from x_zic.parser import parse_zone_line, parse_rule_line
# Parse individual lines
zone_line = "Zone America/New_York -5:00 US E%sT"
zone = parse_zone_line(zone_line)
rule_line = "Rule US 2007 max - Mar Sun>=8 2:00 1:00 D"
rule = parse_rule_line(rule_line)
from x_zic.analysis import stats
from x_zic.export import to_dataframe
# Get statistics
zone_stats = stats.count_zones_by_region()
dst_stats = stats.dst_coverage(2024)
# Export to pandas
df_zones = to_dataframe(read_zones())
df_rules = to_dataframe(read_rules())
print(f"Zones per region: {zone_stats}")
print(f"DST coverage: {dst_stats['percentage']:.1f}%")
Function | Description |
---|---|
read_zones(region=None) |
Read all zones or specific region |
get_transitions(zone_name, start_year, end_year) |
Get DST/offset transitions |
parse_zone_file(filename) |
Parse specific zone file |
Function | Description |
---|---|
parse_zone(file, loader) |
Parse zone file to objects |
parse_rule(file, loader) |
Parse rule file to objects |
parse_link(file, loader) |
Parse link file to objects |
parse_leap(file, loader) |
Parse leap seconds file |
Function | Description |
---|---|
list_regions() |
Get available region names |
get_zones_by_region(region, loader) |
Get zones from region |
get_rules_by_region(region, loader) |
Get rules from region |
{
'name': 'America/New_York',
'offset': '-5:00',
'rules': 'US',
'format': 'E%sT',
'until': None,
'region': 'northamerica'
}
{
'name': 'US',
'from_year': 2007,
'to_year': 'max',
'month': 'Mar',
'day': 'Sun>=8',
'time': '2:00',
'save': '1:00',
'letter': 'D'
}
{
'zone': 'America/New_York',
'timestamp': '2024-03-10T07:00:00',
'offset_before': '-05:00',
'offset_after': '-04:00',
'is_dst': True,
'abbrev': 'EDT'
}
The library automatically caches parsed data for instant subsequent loads:
.tzdb_cache/
├── zones.json
├── rules.json
├── links.json
├── leapseconds.json
└── regions.json
Clear cache when needed:
x_zic.clear_cache()
Operation | First Run | Cached Run |
---|---|---|
Load all zones | ~500ms | ~50ms |
Find zone by name | ~10ms | ~1ms |
Calculate transitions | ~100ms | ~20ms |
The parser handles all standard TZDB files:
- Region Files:
africa
,asia
,europe
,northamerica
, etc. - Legacy Files:
backward
,backzone
- Geographic Data:
zone.tab
,zone1970.tab
,iso3166.tab
- Leap Seconds:
leapseconds
,leap-seconds.list
- Compiled Data:
tzdata.zi
zones = read_zones()
dst_zones = [
zone for zone in zones
if zone['rules'] not in ['-', '', None]
]
print(f"Found {len(dst_zones)} DST-observing zones")
transitions = get_transitions('Europe/London', 2023, 2024)
for t in transitions:
change = "DST Start" if t['is_dst'] else "DST End"
print(f"{t['timestamp'][:10]}: {change} ({t['abbrev']})")
from x_zic.geo import read_zonetab
geo_zones = read_zonetab()
us_zones = [z for z in geo_zones if z['country_code'] == 'US']
for zone in us_zones:
print(f"{zone['zone_id']} - {zone['comments']}")
- Fork the repository 80A8 li>
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit changes (
git commit -m 'Add amazing feature'
) - Push to branch (
git push origin feature/amazing-feature
) - Open a Pull Request
# Run all tests
python -m pytest tests/
# Run with coverage
python -m pytest --cov=x_zic tests/
# Specific test module
python -m pytest tests/test_parser.py -v
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
- IANA Time Zone Database for maintaining the official timezone data
- Python datetime and zoneinfo modules for inspiration
- Contributors and users of the library
Ready to parse timezones? Install the library and start with the Quick Start guide!