Parsing Time with Pendulum: Simplify Your Date and Time Operations transforms one of Python’s most notoriously tricky domains — datetime parsing, timezone handling, human-friendly durations, and arithmetic — into something intuitive, reliable, and beautiful. Pendulum builds on Python’s datetime with a fluent, chainable API, smart defaults, timezone awareness, natural language durations, and excellent parsing — all while staying fully compatible with standard datetime objects. In 2026, Pendulum remains a favorite for applications needing clean time handling (APIs, logging, scheduling, data pipelines, user-facing dates) — especially when you want to avoid strftime hell, DST surprises, or manual timedelta math. It pairs beautifully with Polars/pandas/Dask for time-series data and FastAPI/Pydantic for validated timestamps.
Here’s a complete, practical guide to parsing and working with time using Pendulum: installation & import, parsing strings flexibly, accessing components, timezone conversion, formatting, time arithmetic, real-world patterns (earthquake timestamp parsing, relative time display, scheduling), and modern best practices with type hints, performance, timezone awareness, and integration with Polars/pandas/Dask/FastAPI/pydantic.
1. Installation & Basic Parsing — Smart, Forgiving, Powerful
# Install (if needed)
# pip install pendulum
import pendulum
# Parse almost anything intelligently
dt = pendulum.parse("2026-03-10 14:35:22")
print(dt) # 2026-03-10T14:35:22+00:00 (assumes UTC if no tz)
# ISO, natural language, various formats — all work
print(pendulum.parse("March 10, 2026 2:35 PM")) # 2026-03-10T14:35:00+00:00
print(pendulum.parse("tomorrow at 9am")) # aware, relative to now
print(pendulum.parse("2026-03-10T14:35:22Z")) # UTC
print(pendulum.parse("10/03/2026 14:35", tz="Europe/London")) # explicit tz
2. Accessing Components & Human-Friendly Properties
dt = pendulum.now("America/New_York")
print(dt.year, dt.month, dt.day) # 2026 3 10
print(dt.hour, dt.minute, dt.second) # 9 35 22 (local time)
print(dt.weekday) # 1 (Monday=0)
print(dt.isoweekday) # 2 (Monday=1)
# Human-friendly
print(dt.to_date_string()) # 2026-03-10
print(dt.to_time_string()) # 09:35:22
print(dt.to_datetime_string()) # 2026-03-10 09:35:22
print(dt.to_iso8601_string()) # 2026-03-10T09:35:22-04:00
print(dt.to_rfc2822_string()) # Tue, 10 Mar 2026 09:35:22 -0400
3. Timezone Conversion & Awareness — Effortless
utc = pendulum.now("UTC")
print(utc) # 2026-03-10T14:35:22+00:00
# Convert to another zone
ny = utc.in_timezone("America/New_York")
print(ny) # 2026-03-10T09:35:22-05:00 (or -04:00 DST)
tokyo = utc.in_timezone("Asia/Tokyo")
print(tokyo) # 2026-03-10T23:35:22+09:00
# Create with explicit tz
local = pendulum.now("Europe/Paris")
print(local) # aware, with correct offset & DST
Real-world pattern: earthquake timestamp parsing & relative time display
import polars as pl
import pendulum
df = pl.read_csv('earthquakes.csv')
# Parse timestamps with Pendulum (flexible & timezone-aware)
df = df.with_columns(
pl.col('time').map_elements(pendulum.parse, return_dtype=pl.Datetime).alias('dt')
)
# Add relative time since event (human-friendly)
now = pendulum.now("UTC")
df = df.with_columns(
pl.col('dt').map_elements(lambda d: pendulum.instance(d).diff_for_humans(now), return_dtype=pl.String).alias('age')
)
print(df.select('time', 'mag', 'place', 'age').head(5))
# ? Shows "2 days ago", "1 week ago", etc. — perfect for UI/logging
# Time since last quake
last = df['dt'].max()
age = pendulum.instance(last).diff_for_humans()
print(f"Last quake was {age}")
Best practices for Pendulum in Python 2026
- Prefer Pendulum.parse() — over
datetime.strptime— forgiving, handles many formats, auto-tz detection. - Use
in_timezone()— for conversions (automatic DST handling). - Use
diff_for_humans()— for user-facing relative times ("3 hours ago", "yesterday"). - Use
now(tz)— for aware current time:pendulum.now("UTC"). - Use
add()/subtract()— chainable:dt.add(days=7).subtract(hours=3). - Use
start_of()/end_of()—dt.start_of('day'),dt.end_of('month'). - Add type hints —
from pendulum import DateTime; dt: DateTime = pendulum.now(). - Use Polars + Pendulum — parse/map via
map_elements(pendulum.parse)ormap_elements(lambda d: pendulum.instance(d)). - Use pandas + Pendulum —
df['dt'].map(pendulum.instance)for aware datetimes. - Use Pydantic + Pendulum —
pendulum.DateTimefields for validated timestamps. - Use Pendulum in FastAPI — return
pendulum.DateTime— auto JSON serialization. - Use
diff()— for precise deltas:delta = dt1.diff(dt2)?days,hours, etc. - Avoid naive datetimes — always use
now(tz=...)orin_timezone(). - Use
localize()— for naive ? aware conversion (handles DST). - Use
replace()— for component changes (immutable). - Use
format()— chainable formatting:dt.format('YYYY-MM-DD HH:mm:ss').
Pendulum makes datetime parsing, manipulation, timezone handling, and human-friendly output simple, reliable, and beautiful. In 2026, use it for clean time logic, combine with Polars/pandas/Dask for scale, zoneinfo for native TZ, and type hints/Pydantic for safety. Master Pendulum, and you’ll handle dates, times, and timezones effortlessly in any workflow.
Next time you need to parse, shift, format, or display time — reach for Pendulum. It’s Python’s cleanest way to say: “Make time easy — parse anything, convert zones, add durations, and speak human.”