CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-dateutil

Extensions to the standard Python datetime module

Pending
Overview
Eval results
Files

tz.mddocs/

Timezone Support

Comprehensive timezone handling supporting UTC, fixed offsets, system local timezone, tzfile format, Windows registry timezones, iCalendar timezones, POSIX TZ strings, and advanced DST handling.

Capabilities

Core Timezone Classes

UTC Timezone

class tzutc(tzinfo):
    """
    UTC timezone implementation (singleton).
    
    Standard tzinfo methods:
    - utcoffset(dt) -> timedelta(0)
    - dst(dt) -> timedelta(0) 
    - tzname(dt) -> "UTC"
    - fromutc(dt) -> datetime
    - is_ambiguous(dt) -> False
    """

# Predefined UTC instance
UTC = tzutc()

Fixed Offset Timezone

class tzoffset(tzinfo):
    def __init__(self, name, offset):
        """
        Fixed UTC offset timezone.
        
        Parameters:
        - name (str): Timezone name/description
        - offset (timedelta): UTC offset
        """
        
    def utcoffset(self, dt):
        """Return the fixed offset."""
        
    def dst(self, dt):
        """Return timedelta(0) - no DST."""
        
    def tzname(self, dt):
        """Return the timezone name."""

Usage Examples:

from dateutil.tz import tzutc, tzoffset, UTC
from datetime import datetime, timedelta

# UTC timezone
utc_dt = datetime.now(UTC)
utc_dt2 = datetime.now(tzutc())  # Same as UTC

# Fixed offset timezones
eastern_std = tzoffset("EST", timedelta(hours=-5))
india_std = tzoffset("IST", timedelta(hours=5, minutes=30))

dt_est = datetime(2023, 12, 25, 12, 0, tzinfo=eastern_std)
dt_ist = datetime(2023, 12, 25, 12, 0, tzinfo=india_std)

System Local Timezone

class tzlocal(tzinfo):
    """
    System local timezone with automatic DST handling.
    
    Automatically detects system timezone and handles DST transitions.
    """
    
    def utcoffset(self, dt):
        """Return system UTC offset for given datetime."""
        
    def dst(self, dt): 
        """Return DST offset for given datetime."""
        
    def tzname(self, dt):
        """Return system timezone name."""

Usage Examples:

from dateutil.tz import tzlocal
from datetime import datetime

local_tz = tzlocal()
local_time = datetime.now(local_tz)
print(f"Local time: {local_time}")
print(f"UTC offset: {local_tz.utcoffset(local_time)}")
print(f"DST offset: {local_tz.dst(local_time)}")

File-Based Timezones

tzfile - Timezone from File

class tzfile(tzinfo):
    def __init__(self, fileobj, filename=None):
        """
        Timezone from tzfile format (e.g., /usr/share/zoneinfo files).
        
        Parameters:
        - fileobj: File-like object with tzfile data
        - filename (str, optional): Filename for reference
        """
        
    def is_ambiguous(self, dt):
        """
        Check if datetime is ambiguous during DST transition.
        
        Returns:
        bool: True if datetime occurs twice due to DST transition
        """
        
    def fromutc(self, dt):
        """Convert UTC datetime to local timezone."""

Usage Examples:

from dateutil.tz import tzfile
from datetime import datetime

# Load timezone from system file
with open('/usr/share/zoneinfo/America/New_York', 'rb') as f:
    ny_tz = tzfile(f, 'America/New_York')

dt = datetime(2023, 12, 25, 12, 0, tzinfo=ny_tz)
print(f"Time in NY: {dt}")
print(f"Is ambiguous: {ny_tz.is_ambiguous(dt)}")

Advanced Timezone Classes

tzrange - DST Rule-Based Timezone

class tzrange(tzinfo):
    def __init__(self, stdabbr, stdoffset=None, dstabbr=None, dstoffset=None,
                 start=None, end=None):
        """
        Timezone with explicit DST rules.
        
        Parameters:
        - stdabbr (str): Standard time abbreviation
        - stdoffset (timedelta, optional): Standard time UTC offset
        - dstabbr (str, optional): DST abbreviation  
        - dstoffset (timedelta, optional): DST UTC offset
        - start (relativedelta, optional): DST start rule
        - end (relativedelta, optional): DST end rule  
        """

tzstr - POSIX TZ String Timezone

class tzstr(tzrange):
    def __init__(self, s, posix=True):
        """
        Parse timezone from POSIX TZ environment string.
        
        Parameters:
        - s (str): TZ string (e.g., "EST5EDT,M3.2.0,M11.1.0")
        - posix (bool): Use POSIX-style parsing
        """

Usage Examples:

from dateutil.tz import tzstr
from datetime import datetime

# Parse POSIX TZ strings
eastern = tzstr("EST5EDT,M3.2.0,M11.1.0")  # US Eastern
pacific = tzstr("PST8PDT,M3.2.0,M11.1.0")  # US Pacific

dt = datetime(2023, 7, 15, 12, 0, tzinfo=eastern)
print(f"Eastern time: {dt}")
print(f"Pacific time: {dt.astimezone(pacific)}")

tzical - iCalendar Timezone

class tzical:
    def __init__(self, fileobj):
        """
        Parse timezones from iCalendar (.ics) files.
        
        Parameters:
        - fileobj: File-like object with iCalendar data
        """
        
    def get(self, name=None):
        """
        Get timezone by name.
        
        Parameters:
        - name (str, optional): Timezone name, or None for default
        
        Returns:
        tzinfo: Timezone object
        """
        
    def keys(self):
        """
        Get list of available timezone names.
        
        Returns:
        list[str]: Available timezone names
        """

Timezone Resolution Function

def gettz(name=None):
    """
    Get timezone by name with intelligent fallback.
    
    Parameters:
    - name (str, optional): Timezone name or None for local timezone
    
    Returns:
    tzinfo: Appropriate timezone object
    
    Resolution order:
    1. System zoneinfo if available (preferred)
    2. dateutil bundled zoneinfo 
    3. Fixed offset if name looks like offset
    4. Local timezone if name is None
    5. None if unable to resolve
    """

Usage Examples:

from dateutil.tz import gettz
from datetime import datetime

# Get various timezones
utc = gettz('UTC')
local = gettz()  # System local timezone
ny = gettz('America/New_York')
tokyo = gettz('Asia/Tokyo')
london = gettz('Europe/London')

# Fixed offset styles
plus5 = gettz('+05:00')
minus8 = gettz('-0800')

# Create timezone-aware datetime
dt = datetime(2023, 12, 25, 12, 0, tzinfo=ny)
tokyo_time = dt.astimezone(tokyo)

DST and Ambiguous Time Handling

def enfold(dt, fold=1):
    """
    Set fold attribute for ambiguous times during DST transitions.
    
    Parameters:
    - dt (datetime): Datetime to modify
    - fold (int): Fold value (0 or 1)
    
    Returns:
    datetime: Datetime with fold attribute set
    """

def datetime_ambiguous(dt, tz=None):
    """
    Check if datetime is ambiguous in timezone.
    
    Parameters:
    - dt (datetime): Datetime to check
    - tz (tzinfo, optional): Timezone, uses dt.tzinfo if None
    
    Returns:
    bool: True if datetime is ambiguous
    """

def datetime_exists(dt, tz=None):
    """
    Check if datetime exists in timezone.
    
    Parameters:
    - dt (datetime): Datetime to check
    - tz (tzinfo, optional): Timezone, uses dt.tzinfo if None
    
    Returns:
    bool: True if datetime exists (not in DST gap)
    """

def resolve_imaginary(dt):
    """
    Resolve non-existent times during DST transitions.
    
    Parameters:
    - dt (datetime): Potentially non-existent datetime
    
    Returns:
    datetime: Resolved datetime
    """

Usage Examples:

from dateutil.tz import gettz, enfold, datetime_ambiguous, datetime_exists, resolve_imaginary
from datetime import datetime

eastern = gettz('America/New_York')

# DST transition handling
# Fall back: 2023-11-05 01:30 occurs twice
ambiguous_time = datetime(2023, 11, 5, 1, 30, tzinfo=eastern)
print(f"Is ambiguous: {datetime_ambiguous(ambiguous_time)}")

# Specify which occurrence using fold
first_occurrence = enfold(ambiguous_time, fold=0)
second_occurrence = enfold(ambiguous_time, fold=1)

# Spring forward: 2023-03-12 02:30 doesn't exist
nonexistent_time = datetime(2023, 3, 12, 2, 30, tzinfo=eastern)
print(f"Exists: {datetime_exists(nonexistent_time)}")

# Resolve the gap
resolved_time = resolve_imaginary(nonexistent_time)
print(f"Resolved to: {resolved_time}")

Windows Timezone Support

# Available only on Windows
class tzwin(tzinfo):
    """Windows registry-based timezone."""
    
class tzwinlocal(tzinfo):
    """Windows local timezone from registry."""

Advanced Timezone Patterns

Timezone Conversion Chains

from dateutil.tz import gettz
from datetime import datetime

# Create timezone-aware datetime
utc = gettz('UTC')
dt_utc = datetime(2023, 12, 25, 17, 0, tzinfo=utc)

# Convert through multiple timezones
timezones = ['America/New_York', 'Europe/London', 'Asia/Tokyo', 'Australia/Sydney']
converted_times = {}

for tz_name in timezones:
    tz = gettz(tz_name)
    converted_times[tz_name] = dt_utc.astimezone(tz)

for tz_name, dt in converted_times.items():
    print(f"{tz_name}: {dt}")

Business Hours Across Timezones

from dateutil.tz import gettz
from datetime import datetime, time

def is_business_hours(dt, timezone_name):
    """Check if datetime is during business hours in given timezone."""
    tz = gettz(timezone_name)
    local_dt = dt.astimezone(tz)
    
    # Business hours: 9 AM - 5 PM, Monday-Friday
    if local_dt.weekday() >= 5:  # Weekend
        return False
        
    business_start = time(9, 0)
    business_end = time(17, 0)
    
    return business_start <= local_dt.time() <= business_end

# Test across multiple timezones
utc_time = datetime(2023, 12, 25, 14, 0, tzinfo=gettz('UTC'))
timezones = ['America/New_York', 'Europe/London', 'Asia/Tokyo']

for tz in timezones:
    in_hours = is_business_hours(utc_time, tz)
    print(f"{tz}: {'Open' if in_hours else 'Closed'}")

DST Transition Safety

from dateutil.tz import gettz, datetime_exists, resolve_imaginary
from datetime import datetime, timedelta

def safe_add_time(dt, delta):
    """Add time duration while handling DST transitions safely."""
    result = dt + delta
    
    if not datetime_exists(result):
        result = resolve_imaginary(result)
        
    return result

# Example: Add 24 hours during DST transition
eastern = gettz('America/New_York')
before_transition = datetime(2023, 3, 11, 12, 0, tzinfo=eastern)

# Naive addition might hit DST gap
safe_result = safe_add_time(before_transition, timedelta(hours=24))
print(f"Safe result: {safe_result}")

Exception Types

class DeprecatedTzFormatWarning(Warning):
    """Warning raised when parsing deprecated timezone formats."""

Types

from datetime import datetime, timedelta, tzinfo

# Core timezone classes inherit from tzinfo
class tzutc(tzinfo): ...
class tzoffset(tzinfo): ...
class tzlocal(tzinfo): ...
class tzfile(tzinfo): ...
class tzrange(tzinfo): ...
class tzstr(tzrange): ...

# Platform-specific (Windows only)
class tzwin(tzinfo): ...
class tzwinlocal(tzinfo): ...

# iCalendar timezone container
class tzical:
    def get(self, name=None) -> tzinfo: ...
    def keys(self) -> list[str]: ...

# Utility function return types
TzInfo = tzinfo | None

Install with Tessl CLI

npx tessl i tessl/pypi-python-dateutil

docs

easter.md

index.md

parser.md

relativedelta.md

rrule.md

tz.md

utils.md

zoneinfo.md

tile.json