Pattern format¶
Custom format and parse patterns allow you to format datetime values into strings and parse strings into datetime values, using a pattern string that describes the expected format.
Quick example¶
>>> from whenever import Date, Time, OffsetDateTime, hours
>>> Date(2024, 3, 15).format("YYYY/MM/DD")
'2024/03/15'
>>> Date.parse("2024/03/15", format="YYYY/MM/DD")
Date("2024-03-15")
>>> OffsetDateTime(2024, 3, 15, 14, 30, offset=+2).format(
... "EEE, DD MMM YYYY hh:mm:ssxxx"
... )
'Fri, 15 Mar 2024 14:30:00+02:00'
Specifiers¶
Each pattern is a string containing specifiers and literal text. Specifiers are sequences of the same letter that are replaced by the corresponding value.
Date specifiers¶
Time specifiers¶
Symbol |
Meaning |
Pattern |
Example output |
|---|---|---|---|
|
hour |
|
|
|
hour (12-hour) |
|
|
|
minute |
|
|
|
second |
|
|
|
second, optional [3] |
|
|
|
fractional seconds, exact digits |
|
|
|
fractional seconds, trimmed [4] |
|
|
|
AM/PM [5] |
|
|
Optional seconds
SS omits the seconds component entirely when both seconds and
nanoseconds are zero, allowing compact times like 14:30 alongside full
times like 14:30:05 in the same format string.
When seconds or nanoseconds are non-zero,
SSwrites two zero-padded digitsWhen both are zero, nothing is written. Any preceeding colon disappears as well.
>>> Time(14, 30, 0).format("hh:mm:SS")
'14:30'
>>> Time(14, 30, 5).format("hh:mm:SS")
'14:30:05'
>>> Time(14, 30, 0, nanosecond=500_000_000).format("hh:mm:SS")
'14:30:00'
>>> Time(14, 30, 0).format("hh:mm:SS.FFF")
'14:30'
>>> Time(14, 30, 0, nanosecond=500_000_000).format("hh:mm:SS.FFF")
'14:30:00.5'
Offset and timezone specifiers¶
See Timezones for background on timezones, offsets, and abbreviations.
Symbol |
Meaning |
Pattern |
Example output |
|---|---|---|---|
|
Offset hours and minutes |
|
|
|
Offset hours and minutes, with |
|
|
|
IANA timezone ID |
|
|
|
Timezone abbreviation [6] |
|
|
Choosing between x and X
Use uppercase X when you want Z for zero offset
(e.g. Instant formatting).
Use lowercase x when you always want a numeric offset
(e.g. OffsetDateTime formatting).
>>> ZonedDateTime(2024, 7, 15, 14, 30, tz="Europe/Paris").format(
... "YYYY-MM-DD hh:mm zz"
... )
'2024-07-15 14:30 CEST'
>>> ZonedDateTime.parse(
... "2024-07-15 14:30+02:00[Europe/Paris]",
... format="YYYY-MM-DD hh:mmxxx'['VV']'",
... )
ZonedDateTime("2024-07-15 14:30:00+02:00[Europe/Paris]")
Supported specifiers per type¶
Type |
Date |
Time |
|
|
|---|---|---|---|---|
✅ |
❌ |
❌ |
❌ |
|
❌ |
✅ |
❌ |
❌ |
|
✅ |
✅ |
❌ |
❌ |
|
✅ |
✅ |
✅ |
❌ |
|
✅ |
✅ |
✅ |
✅ |
|
✅ |
✅ |
✅ |
❌ |
Literal text¶
Common non-letter characters (:, -, /, ., ,, ;,
_, (, ), digits, spaces, and other ASCII
punctuation) are treated as literals by default:
>>> Date(2024, 3, 15).format("YYYY/MM/DD")
'2024/03/15'
Letters must be quoted with single quotes to be used as literals. This prevents accidental use of reserved characters and keeps options open for future specifiers:
>>> Date(2024, 3, 15).format("YYYY'xx'MM")
'2024xx03'
To include a literal single quote, use '':
>>> Date(2024, 3, 15).format("YYYY''MM")
"2024'03"
Restrictions¶
ASCII-only: Pattern strings must contain only ASCII characters. Non-ASCII characters raise
ValueError.Reserved characters:
<,>,[,],{,}, and#are reserved for future use and cannot appear unquoted.No duplicate fields: A pattern cannot contain two specifiers that set the same value. For example,
MMandMMMboth set the month, so"DD MM MMM YYYY"is invalid.
Parsing requirements¶
Some types require specific fields in the parse pattern:
OffsetDateTime.parse()requires an offset (x/X)ZonedDateTime.parse()requiresVV(timezone ID). An offset (x/X) is optional but recommended for DST disambiguation.Instant.parse()requires an offset (x/X)
All types that include date fields require YYYY, MM, and DD.
A second value of 60 (leap second) is accepted and normalized to 59.
See Are leap seconds supported? for details.
Comparison with strftime¶
The parse_strptime() methods on OffsetDateTime and
PlainDateTime are deprecated in favor of
parse(). Here’s a migration guide:
strftime |
Pattern |
Notes |
|---|---|---|
|
|
|
|
|
Format only |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note: |
|
|
Note: |
|
|
|
|
|
|
|
|
microseconds (6 digits) |
|
|
|
|
|
|
|
|
|
|
— |
Abbreviations are not supported for parsing. See Timezones. |