Python datetimes made easy with timezone-aware datetime manipulation and human-readable formatting
—
Comprehensive timezone handling with IANA database support. Pendulum provides robust timezone functionality including timezone creation, conversion, DST handling, and local timezone management for testing scenarios.
Functions for creating various types of timezone objects.
def timezone(name: str | int) -> Timezone | FixedTimezone:
"""
Create timezone from name or offset.
Parameters:
- name: IANA timezone name (e.g., 'Europe/Paris') or UTC offset in hours
Returns:
Timezone | FixedTimezone: Timezone object
"""
def local_timezone() -> Timezone:
"""
Get system local timezone.
Returns:
Timezone: Local timezone object
"""Functions for managing timezone settings and querying available timezones.
def set_local_timezone(tz: str | Timezone) -> None:
"""
Set local timezone for testing purposes (persistent).
Parameters:
- tz: Timezone name or Timezone object
"""
def test_local_timezone(tz: str | Timezone):
"""
Context manager to temporarily set local timezone.
Parameters:
- tz: Timezone name or Timezone object
Usage:
with pendulum.test_local_timezone('Europe/Paris'):
# Local timezone is temporarily Paris
dt = pendulum.now('local')
"""
def timezones() -> set[str]:
"""
Get set of all available IANA timezone names.
Returns:
set[str]: Set of timezone names
"""IANA timezone representation with dynamic DST handling.
class Timezone:
def __init__(self, key: str):
"""
Create timezone from IANA key.
Parameters:
- key: IANA timezone name (e.g., 'America/New_York')
"""
def convert(
self,
dt: DateTime,
raise_on_unknown_times: bool = False
) -> DateTime:
"""
Convert DateTime to this timezone.
Parameters:
- dt: DateTime to convert
- raise_on_unknown_times: Raise exception for ambiguous times
Returns:
DateTime: DateTime in this timezone
"""
def datetime(
self,
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
microsecond: int = 0
) -> DateTime:
"""
Create DateTime in this timezone.
Parameters:
- year: Year
- month: Month
- day: Day
- hour: Hour
- minute: Minute
- second: Second
- microsecond: Microsecond
Returns:
DateTime: DateTime in this timezone
"""
@property
def name(self) -> str:
"""IANA timezone name"""Fixed UTC offset timezone representation.
class FixedTimezone:
def __init__(self, offset: int, name: str | None = None):
"""
Create fixed offset timezone.
Parameters:
- offset: UTC offset in seconds
- name: Optional timezone name
"""
def convert(
self,
dt: DateTime,
raise_on_unknown_times: bool = False
) -> DateTime:
"""
Convert DateTime to this timezone.
Parameters:
- dt: DateTime to convert
- raise_on_unknown_times: Ignored for fixed timezones
Returns:
DateTime: DateTime in this timezone
"""
def datetime(
self,
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
microsecond: int = 0
) -> DateTime:
"""
Create DateTime in this timezone.
Returns:
DateTime: DateTime in this timezone
"""
def utcoffset(self, dt) -> timedelta:
"""
Get UTC offset as timedelta.
Parameters:
- dt: DateTime (ignored for fixed offset)
Returns:
timedelta: UTC offset
"""
def dst(self, dt) -> timedelta:
"""
Get DST offset (always zero for fixed timezone).
Parameters:
- dt: DateTime (ignored)
Returns:
timedelta: Always timedelta(0)
"""
def tzname(self, dt) -> str:
"""
Get timezone name.
Parameters:
- dt: DateTime (ignored)
Returns:
str: Timezone name
"""
@property
def name(self) -> str:
"""Timezone name"""
@property
def offset(self) -> int:
"""UTC offset in seconds"""Pre-defined timezone objects for common use cases.
UTC: FixedTimezone # UTC timezone (offset 0)import pendulum
# Create timezones by name
paris_tz = pendulum.timezone('Europe/Paris')
tokyo_tz = pendulum.timezone('Asia/Tokyo')
utc_tz = pendulum.timezone('UTC')
# Create timezone from UTC offset (hours)
plus_5_tz = pendulum.timezone(5) # +5 hours
minus_8_tz = pendulum.timezone(-8) # -8 hours
# Create fixed offset timezone through timezone() with integer offset
fixed_tz = pendulum.timezone(5) # +5 hours
# Use predefined UTC
utc_dt = pendulum.now(pendulum.UTC)
print(f"Paris timezone: {paris_tz.name}")
print(f"Fixed timezone offset: {fixed_tz.offset} seconds")import pendulum
# Create DateTime in one timezone
utc_dt = pendulum.now('UTC')
print(f"UTC: {utc_dt}")
# Convert to different timezones
paris_dt = utc_dt.in_timezone('Europe/Paris')
tokyo_dt = utc_dt.in_timezone('Asia/Tokyo')
local_dt = utc_dt.in_timezone('local')
print(f"Paris: {paris_dt}")
print(f"Tokyo: {tokyo_dt}")
print(f"Local: {local_dt}")
# Using timezone objects
paris_tz = pendulum.timezone('Europe/Paris')
converted = utc_dt.in_timezone(paris_tz)
print(f"Converted: {converted}")
# Direct conversion with timezone.convert()
converted2 = paris_tz.convert(utc_dt)
print(f"Direct convert: {converted2}")import pendulum
# Create DateTime directly in timezone
paris_dt = pendulum.datetime(2024, 6, 15, 14, 30, tz='Europe/Paris')
tokyo_dt = pendulum.datetime(2024, 6, 15, 14, 30, tz='Asia/Tokyo')
# Using timezone objects
paris_tz = pendulum.timezone('Europe/Paris')
tz_dt = paris_tz.datetime(2024, 6, 15, 14, 30)
# Using module-level functions
local_dt = pendulum.local(2024, 6, 15, 14, 30) # Local timezone
utc_dt = pendulum.datetime(2024, 6, 15, 14, 30) # UTC (default)
print(f"Paris: {paris_dt} (offset: {paris_dt.offset_hours}h)")
print(f"Tokyo: {tokyo_dt} (offset: {tokyo_dt.offset_hours}h)")
print(f"From timezone object: {tz_dt}")import pendulum
# DST transition examples
# Spring forward (2024-03-31 in Europe/Paris)
paris_tz = pendulum.timezone('Europe/Paris')
# Before DST transition (CET = UTC+1)
before_dst = paris_tz.datetime(2024, 3, 31, 1, 30)
print(f"Before DST: {before_dst} (DST: {before_dst.is_dst()})")
# After DST transition (CEST = UTC+2)
after_dst = paris_tz.datetime(2024, 3, 31, 3, 30)
print(f"After DST: {after_dst} (DST: {after_dst.is_dst()})")
# Check DST status
summer_dt = paris_tz.datetime(2024, 7, 15, 12, 0)
winter_dt = paris_tz.datetime(2024, 1, 15, 12, 0)
print(f"Summer DST: {summer_dt.is_dst()}") # True
print(f"Winter DST: {winter_dt.is_dst()}") # Falseimport pendulum
# During DST transitions, some times can be ambiguous
# Fall back transition (2024-10-27 in Europe/Paris)
paris_tz = pendulum.timezone('Europe/Paris')
# This time occurs twice during fall-back
try:
# By default, Pendulum handles ambiguous times gracefully
ambiguous_dt = paris_tz.datetime(2024, 10, 27, 2, 30)
print(f"Ambiguous time handled: {ambiguous_dt}")
except Exception as e:
print(f"Error: {e}")
# Explicitly raise on unknown times
try:
strict_dt = paris_tz.datetime(
2024, 10, 27, 2, 30,
raise_on_unknown_times=True
)
except Exception as e:
print(f"Strict mode error: {e}")
# Use fold parameter for disambiguation
dt_fold_0 = pendulum.datetime(
2024, 10, 27, 2, 30,
tz='Europe/Paris',
fold=0 # First occurrence
)
dt_fold_1 = pendulum.datetime(
2024, 10, 27, 2, 30,
tz='Europe/Paris',
fold=1 # Second occurrence
)
print(f"Fold 0: {dt_fold_0}")
print(f"Fold 1: {dt_fold_1}")import pendulum
# Get current local timezone
local_tz = pendulum.local_timezone()
print(f"System local timezone: {local_tz.name}")
# Create DateTime in local timezone
local_now = pendulum.now('local')
print(f"Local now: {local_now}")
# Temporarily change local timezone for testing
with pendulum.test_local_timezone('Asia/Tokyo'):
temp_local = pendulum.now('local')
print(f"Temporary local (Tokyo): {temp_local}")
# Local timezone restored after context
restored = pendulum.now('local')
print(f"Restored local: {restored}")
# Permanently set local timezone (for testing)
pendulum.set_local_timezone('Europe/Paris')
new_local = pendulum.now('local')
print(f"New local (Paris): {new_local}")import pendulum
# Get all available timezones
all_timezones = pendulum.timezones()
print(f"Total timezones: {len(all_timezones)}")
# Filter for specific regions
europe_timezones = {tz for tz in all_timezones if tz.startswith('Europe/')}
america_timezones = {tz for tz in all_timezones if tz.startswith('America/')}
print(f"Europe timezones: {len(europe_timezones)}")
print(f"America timezones: {len(america_timezones)}")
# Some examples
print("Some Europe timezones:")
for tz in sorted(list(europe_timezones)[:5]):
print(f" {tz}")
# Check if timezone exists
tz_name = 'Europe/London'
if tz_name in all_timezones:
london_tz = pendulum.timezone(tz_name)
print(f"London timezone: {london_tz.name}")import pendulum
# Create fixed offset timezones using FixedTimezone class directly
from pendulum.tz.timezone import FixedTimezone
plus_5_30 = FixedTimezone(int(5.5 * 3600)) # +05:30 (India)
minus_3_30 = FixedTimezone(int(-3.5 * 3600)) # -03:30 (Newfoundland)
# Create DateTimes with fixed offsets
india_dt = pendulum.datetime(2024, 6, 15, 14, 30, tz=plus_5_30)
nfld_dt = pendulum.datetime(2024, 6, 15, 14, 30, tz=minus_3_30)
print(f"India time: {india_dt}")
print(f"Newfoundland time: {nfld_dt}")
# Fixed offset properties
print(f"India offset: {plus_5_30.offset} seconds")
print(f"India offset hours: {plus_5_30.offset / 3600}")
# DST is always 0 for fixed timezones
print(f"DST offset: {plus_5_30.dst(None)}")Install with Tessl CLI
npx tessl i tessl/pypi-pendulum