Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Apache Airflow Timezone Utilities

From Leeroopedia
Revision as of 14:11, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Apache_Airflow_Timezone_Utilities.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Knowledge Sources
Domains Core_Infrastructure, Datetime_Handling
Last Updated 2026-02-08 21:00 GMT

Overview

Timezone utility module providing functions for creating, converting, formatting, and parsing timezone-aware datetimes using Pendulum, with transparent compatibility across Pendulum 2 and Pendulum 3 versions.

Description

The timezone module is a foundational utility used throughout Airflow to ensure all datetime values are timezone-aware. It wraps the Pendulum library and provides a consistent API that works across both Pendulum 2 and Pendulum 3.

Key design aspects:

  • Initialized timezone: A module-level _Timezone class tracks the configured default timezone (set via initialize() at Airflow startup). All functions that need a timezone default to this initialized value rather than requiring it as a parameter.
  • Pendulum version detection: The _PENDULUM3 boolean flag is computed at import time from the installed Pendulum version. Functions like parse_timezone() and local_timezone() use this flag to call the correct Pendulum API.
  • Naive/aware enforcement: Functions like make_aware() and make_naive() include runtime checks to prevent accidental double-conversion.
  • UTC constant: The utc module-level constant is set to pendulum.UTC for convenient access.

Usage

from airflow_shared.timezones.timezone import utcnow, convert_to_utc, make_aware, parse

# Get current UTC time
now = utcnow()

# Convert a naive datetime to UTC
import datetime as dt
naive_dt = dt.datetime(2024, 6, 15, 10, 30, 0)
utc_dt = convert_to_utc(make_aware(naive_dt))

# Parse a time string
parsed = parse("2024-06-15T10:30:00+02:00")

Code Reference

Source Location

  • Repository: Apache_Airflow
  • File: shared/timezones/src/airflow_shared/timezones/timezone.py

Constants

utc = pendulum.UTC
# UTC Timezone as a tzinfo instance. Actual value depends on pendulum version:
# - Timezone("UTC") in pendulum 3
# - FixedTimezone(0, "UTC") in pendulum 2

_PENDULUM3 = version.parse(metadata.version("pendulum")).major == 3

Key Functions

Awareness Checks

def is_localized(value: dt.datetime) -> bool:
    """Determine if a given datetime.datetime is aware."""

def is_naive(value) -> bool:
    """Determine if a given datetime.datetime is naive."""

Time Creation

def utcnow() -> dt.datetime:
    """Get the current date and time in UTC."""

def datetime(*args, **kwargs) -> dt.datetime:
    """Wrap around datetime.datetime to add the initialized timezone if tzinfo not specified."""

def from_timestamp(timestamp: int | float, tz: str | FixedTimezone | Timezone = utc) -> DateTime:
    """Parse timestamp and return DateTime in a given time zone."""

Conversion

def convert_to_utc(value: dt.datetime | None) -> DateTime | None:
    """Create a datetime with the default timezone added if none is associated,
    then convert to UTC."""

def make_aware(value: dt.datetime | None, timezone: dt.tzinfo | None = None) -> dt.datetime | None:
    """Make a naive datetime.datetime in a given time zone aware."""

def make_naive(value, timezone=None):
    """Make an aware datetime.datetime naive in a given time zone."""

def coerce_datetime(v: dt.datetime | None, tz: dt.tzinfo | None = None) -> DateTime | None:
    """Convert v into a timezone-aware pendulum.DateTime."""

Parsing

def parse(string: str, timezone=None, *, strict=False) -> DateTime:
    """Parse a time string and return an aware datetime."""

def parse_timezone(name: str | int) -> FixedTimezone | Timezone:
    """Parse timezone and return one of the pendulum Timezone objects.
    Handles Pendulum 2/3 API differences transparently."""

Formatting

def td_format(td_object: None | dt.timedelta | float | int) -> str | None:
    """Format a timedelta object or float/int into a readable string.
    Example: timedelta(seconds=3752) -> '1h:2M:32s'
    Returns '<1s' for sub-second durations."""

Initialization

def initialize(default_timezone: str) -> None:
    """Initialize the default timezone for the timezone library.
    Called automatically by airflow-core and task-sdk during startup.
    Pass 'system' to use the local system timezone."""

def local_timezone() -> FixedTimezone | Timezone:
    """Return the local timezone."""

Import

from airflow_shared.timezones.timezone import utcnow, convert_to_utc, make_aware, parse
from airflow_shared.timezones.timezone import (
    utc, is_localized, is_naive, make_naive,
    coerce_datetime, td_format, parse_timezone,
    local_timezone, initialize, from_timestamp,
)

I/O Contract

Inputs

Name Type Required Description
value datetime.datetime or None Yes (varies) The datetime to convert, check, or format
timezone dt.tzinfo or None No Target timezone; defaults to the initialized timezone
string str Yes (for parse) A date/time string in ISO 8601 or other parseable format
timestamp int or float Yes (for from_timestamp) Epoch time in seconds
default_timezone str Yes (for initialize) IANA timezone string or "system"
td_object timedelta, float, int, or None Yes (for td_format) Duration to format

Outputs

Name Type Description
Aware datetime pendulum.DateTime or dt.datetime Timezone-aware datetime object
Naive datetime dt.datetime Datetime with tzinfo stripped
Boolean bool Result of is_localized() or is_naive()
Formatted string str or None Human-readable duration (e.g., "1h:2M:32s") or None
Timezone FixedTimezone or Timezone Parsed Pendulum timezone object

Usage Examples

Timezone Initialization at Startup

from airflow_shared.timezones.timezone import initialize

# Use UTC as the default timezone
initialize("UTC")

# Or use a specific timezone
initialize("America/New_York")

# Or use the system's local timezone
initialize("system")

Working with Task Schedules

from airflow_shared.timezones.timezone import utcnow, convert_to_utc, make_aware, parse
import datetime as dt

# Record when a task started
start_time = utcnow()

# Convert a user-provided naive datetime to UTC
user_input = dt.datetime(2024, 12, 25, 8, 0, 0)
utc_time = convert_to_utc(make_aware(user_input))

# Parse a schedule string
next_run = parse("2024-12-25T08:00:00", timezone="US/Eastern")

Formatting Task Durations

from airflow_shared.timezones.timezone import td_format
import datetime as dt

duration = dt.timedelta(hours=2, minutes=15, seconds=42)
print(td_format(duration))  # "2h:15M:42s"

short_duration = dt.timedelta(milliseconds=500)
print(td_format(short_duration))  # "<1s"

# Also works with raw seconds
print(td_format(7384))  # "2h:3M:4s"

Pendulum 2/3 Compatibility

from airflow_shared.timezones.timezone import parse_timezone, local_timezone

# Works regardless of installed Pendulum version
eastern = parse_timezone("US/Eastern")
local = local_timezone()

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment