Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 GitHub - mlotfic/x-zic: 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.
Nothing Special   »   [go: up one dir, main page]

Skip to content
/ x-zic Public

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.

License

Notifications You must be signed in to change notification settings

mlotfic/x-zic

Repository files navigation

TZDB Parser

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.

Features

  • 🚀 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

Installation

pip install x-zic

Or clone from source:

git clone https://github.com/mlotfic/x-zic
cd x-zic
pip install -e .

Quick Start

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']})")

Basic Usage

Reading Timezone Data

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)

Working with Transitions

# 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']}")

Geographic Data

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']})")

Advanced Usage

Custom Configuration

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)

Low-level Parsing

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)

Analysis and Export

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}%")

API Reference

Core Functions

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

Parser Module

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

Regions Module

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

Data Models

Zone

{
    'name': 'America/New_York',
    'offset': '-5:00', 
    'rules': 'US',
    'format': 'E%sT',
    'until': None,
    'region': 'northamerica'
}

Rule

{
    'name': 'US',
    'from_year': 2007,
    'to_year': 'max',
    'month': 'Mar',
    'day': 'Sun>=8',
    'time': '2:00',
    'save': '1:00',
    'letter': 'D'
}

Transition

{
    'zone': 'America/New_York',
    'timestamp': '2024-03-10T07:00:00',
    'offset_before': '-05:00',
    'offset_after': '-04:00', 
    'is_dst': True,
    'abbrev': 'EDT'
}

Cache System

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()

Performance

Operation First Run Cached Run
Load all zones ~500ms ~50ms
Find zone by name ~10ms ~1ms
Calculate transitions ~100ms ~20ms

File Support

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

Examples

Find All DST-Observing Zones

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")

Calculate Offset Changes

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']})")

Geographic Queries

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']}")

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Testing

# 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

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Acknowledgments

  • IANA Time Zone Database for maintaining the official timezone data
  • Python datetime and zoneinfo modules for inspiration
  • Contributors and users of the library

Support


Ready to parse timezones? Install the library and start with the Quick Start guide!

About

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.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published
0