python-dateutil
python-dateutil provides powerful extensions to Python's standard datetime module, including flexible date/time string parsing, relative delta arithmetic, recurrence rules (RFC 2445 superset), and rich timezone support via tzfile, TZ strings, and Windows registry. Current version is 2.9.0.post0 (released 2024-03-01). The project is considered functionally stable but upstream activity is slow; Fedora has flagged it as unmaintained. The PyPI install name (python-dateutil) differs from the importable name (dateutil).
Warnings
- gotcha parser.parse() silently guesses ambiguous dates like '04/05/2024' using dayfirst=False (MM/DD) by default. Non-US date strings will be parsed incorrectly unless dayfirst=True is set explicitly.
- gotcha parser.parse() returns a timezone-naive datetime when no timezone is present in the input string, which can silently cause incorrect comparisons with aware datetimes.
- breaking Since 2.8.1 parse() raises dateutil.parser.ParserError (a ValueError subclass) instead of plain ValueError. Code catching ValueError still works, but catching only the base Exception may need updating.
- gotcha fuzzy=True parsing can silently extract numbers from arbitrary strings as date components (e.g. parse('lbl2vec at 7pm', fuzzy=True) extracts '2' as a day). This makes fuzzy parsing unsafe for untrusted or unexpected input.
- gotcha rrule dtstart is NOT included as the first occurrence unless it independently satisfies the recurrence rule — this diverges from RFC 2445 behavior.
- gotcha gettz() returns None silently when a timezone name cannot be resolved (e.g. on Windows without the tzdata package installed). Passing None as tzinfo produces a naive datetime without error.
- deprecated The project still ships the six compatibility shim as a hard dependency. Fedora has flagged the project as effectively unmaintained upstream with possible unaddressed security issues. New greenfield projects should consider zoneinfo (Python 3.9+ stdlib) + dateutil only for relativedelta/rrule features.
Install
-
pip install python-dateutil
Imports
- parser.parse
from dateutil import parser; parser.parse('2024-01-15') - parser.isoparse
from dateutil.parser import isoparse
- relativedelta
from dateutil.relativedelta import relativedelta
- rrule / DAILY / WEEKLY / MONTHLY / YEARLY
from dateutil.rrule import rrule, DAILY, WEEKLY, MONTHLY, YEARLY, rruleset
- gettz
from dateutil.tz import gettz, tzutc, tzlocal
- ParserError
from dateutil.parser import ParserError
Quickstart
from datetime import datetime
from dateutil import parser
from dateutil.relativedelta import relativedelta
from dateutil.tz import gettz, tzutc
# 1. Flexible string parsing
dt = parser.parse("March 15, 2024 3:30 PM")
print("Parsed:", dt)
# 2. ISO 8601 with timezone
dt_aware = parser.isoparse("2024-03-15T15:30:00+05:30")
print("ISO aware:", dt_aware)
# 3. Relative delta arithmetic (month-aware)
now = datetime(2024, 1, 31, tzinfo=tzutc())
one_month_later = now + relativedelta(months=1)
print("One month later:", one_month_later) # 2024-02-29 (leap year)
# 4. Timezone-aware datetime
nyc = gettz("America/New_York")
if nyc is None:
raise RuntimeError("Could not resolve timezone; install tzdata package")
dt_nyc = datetime(2024, 3, 15, 12, 0, tzinfo=nyc)
print("NYC time:", dt_nyc)
# 5. Ambiguous date: always set dayfirst/yearfirst explicitly
ambiguous = parser.parse("04/05/2024", dayfirst=False) # May 4
print("MM/DD:", ambiguous.date())