Formatting and parsing

Whenever supports formatting and parsing standardized formats

ISO 8601

All types in whenever use ISO8601 as their canonical, round-trippable, string representation. You can even instantiate objects directly from their ISO 8601 string representation:

>>> Instant("2023-12-28T11Z")
Instant("2023-12-28 11:00:00Z")
>>> PlainDateTime("20231228T1130")
PlainDateTime("2023-12-28 11:30:00")

Below are the default string formats you get for calling each type’s format_iso() method:

Type

Default string format

Instant

YYYY-MM-DDTHH:MM:SSZ

PlainDateTime

YYYY-MM-DDTHH:MM:SS

ZonedDateTime

YYYY-MM-DDTHH:MM:SS±HH:MM[IANA TZ ID] [1]

OffsetDateTime

YYYY-MM-DDTHH:MM:SS±HH:MM

See the reference documentation for more details on formatting and parsing ISO 8601 strings.

RFC 2822

RFC 2822 is another common format for representing datetimes. It’s used in email headers and HTTP headers. The format is:

Weekday, DD Mon YYYY HH:MM:SS ±HHMM

For example: Tue, 13 Jul 2021 09:45:00 -0900

Use the methods format_rfc2822() and parse_rfc2822() to format and parse to this format, respectively:

>>> d = OffsetDateTime(2023, 12, 28, 11, 30, offset=+5)
>>> d.format_rfc2822()
'Thu, 28 Dec 2023 11:30:00 +0500'
>>> OffsetDateTime.parse_rfc2822('Tue, 13 Jul 2021 09:45:00 -0900')
OffsetDateTime("2021-07-13 09:45:00-09:00")

Custom formats

All datetime types support custom format and parse patterns via the format() and parse() methods. Patterns use specifiers like YYYY, MM, DD, hh, mm, ss.

>>> OffsetDateTime(2024, 3, 15, 14, 30, offset=+2).format(
...     "ddd, DD MMM YYYY hh:mm:ssxxx"
... )
'Fri, 15 Mar 2024 14:30:00+02:00'
>>> Date.parse("15 Mar 2024", format="DD MMM YYYY")
Date("2024-03-15")
>>> ZonedDateTime.parse(
...     "2024-03-15 14:30+01:00[Europe/Paris]",
...     format="YYYY-MM-DD hh:mmxxx'['VV']'",
... )
ZonedDateTime("2024-03-15 14:30:00+01:00[Europe/Paris]")

See the pattern format reference for the full list of specifiers and details.

Deprecated since version 0.10.0: The parse_strptime() methods on OffsetDateTime and PlainDateTime are deprecated. Use parse() with a pattern string instead, or convert from a stdlib datetime: OffsetDateTime(datetime.strptime(...)).

Pydantic integration

Warning

Pydantic support is still in beta and may change in the future.

whenever types support basic serialization and deserialization with Pydantic. The behavior is identical to the parse_iso() and format_iso() methods.

>>> from pydantic import BaseModel
>>> from whenever import ZonedDateTime, TimeDelta
...
>>> class Event(BaseModel):
...     start: ZonedDateTime
...     duration: TimeDelta
...
>>> event = Event(
...     start=ZonedDateTime(2023, 2, 23, hour=20, tz="Europe/Amsterdam"),
...     duration=TimeDelta(hours=2, minutes=30),
... )
>>> d = event.model_dump_json()
'{"start":"2023-02-23T20:00:00+01:00[Europe/Amsterdam]","duration":"PT2H30M"}'

Note

Whenever’s parsing is stricter then Pydantic’s default datetime parsing behavior. More flexible parsing may be added in the future.