Skip to main content

Date and Time Formatting

To format date and time objects into strings using Django's custom format specifiers, use the utilities provided in django.utils.dateformat. This system uses a syntax inspired by PHP's date() function.

Formatting a Datetime Object

The most common way to format a datetime or date object is using the format() convenience function.

from datetime import datetime
from django.utils.dateformat import format

# Current date and time
now = datetime.now()

# Format: Day of month with suffix, Full Month, Year, 24h Hour:Minutes
# Example Output: "7th October 2023 14:30"
result = format(now, 'jS F Y H:i')
print(result)

Formatting Time-Only Objects

If you are working specifically with datetime.time objects, use the time_format() function.

from datetime import time
from django.utils.dateformat import time_format

t = time(14, 30)

# Format: 12h hour:minutes with a.m./p.m.
# Example Output: "2:30 p.m."
result = time_format(t, 'f a')
print(result)

Using the DateFormat and TimeFormat Classes

For more control, or if you need to perform multiple formatting operations on the same object, you can instantiate DateFormat or TimeFormat directly.

from datetime import datetime
from django.utils.dateformat import DateFormat

d = datetime(2023, 10, 7, 11, 39)
df = DateFormat(d)

# You can call the format method
print(df.format('Y-m-d')) # "2023-10-07"

# Or call individual format character methods directly
print(df.S()) # "rd" (for the 7th)
print(df.L()) # False (not a leap year)

Escaping Literal Characters

If you want to include a character in your format string that is also a format specifier (like 'Y' or 'H'), you must escape it with a backslash.

from datetime import datetime
from django.utils.dateformat import format

my_date = datetime(1979, 7, 8)

# Escaping 'C', 'E', and 'T' to treat them as literals
# Result: "1979 189 CET"
result = format(my_date, r"Y z \C\E\T")

Common Format Specifiers

The following specifiers are implemented in DateFormat and TimeFormat:

SpecifierDescriptionExample
Y4-digit year2023
y2-digit year23
FFull textual monthOctober
mMonth with leading zeros01 to 12
jDay of month without leading zeros1 to 31
SEnglish ordinal suffix for dayst, nd, rd, th
H24-hour hour with leading zeros00 to 23
iMinutes with leading zeros00 to 59
PTime with 'midnight'/'noon' (Proprietary)1:30 p.m., noon
fTime with optional minutes (Proprietary)1, 1:30
cISO 8601 format2023-10-07T11:39:00
rRFC 5322 formatted dateSat, 07 Oct 2023 11:39:00 +0000

Troubleshooting: Time Specifiers on Date Objects

A common error occurs when trying to use time-related format specifiers (like H, i, s) on a datetime.date object. The Formatter class explicitly prevents this to avoid misleading output.

from datetime import date
from django.utils.dateformat import format

d = date(2023, 10, 7)

# This will raise a TypeError:
# "The format for date objects may not contain time-related format specifiers (found 'H')."
try:
format(d, 'Y-m-d H:i')
except TypeError as e:
print(e)

To fix this, convert your date object to a datetime object before formatting:

from datetime import datetime, date
from django.utils.dateformat import format

d = date(2023, 10, 7)
dt = datetime.combine(d, datetime.min.time())
print(format(dt, 'Y-m-d H:i')) # "2023-10-07 00:00"

Timezone Handling

TimeFormat (and by extension DateFormat) handles timezones based on the object provided:

  • If a naive datetime is provided, it uses the default timezone (configured via settings.TIME_ZONE).
  • If an aware datetime is provided, it uses the object's own timezone information.
  • Timezone specifiers (like e, O, T, Z) return an empty string if no timezone information is available (e.g., when formatting a date object).