Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/humanize/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,15 @@ def _convert_aware_datetime(
return value


def naturalday(value: dt.date | dt.datetime, format: str = "%b %d") -> str:
def naturalday(
value: dt.date | dt.datetime, format: str = "%b %d", *, weekday: bool = False
) -> str:
"""Return a natural day.

For date values that are tomorrow, today or yesterday compared to
present day return representing string. Otherwise, return a string
formatted according to `format`.
present day return representing string. If `weekday` is True, dates within
6 days past or future will return weekday names (e.g. 'this Monday',
'last Friday'). Otherwise, return a string formatted according to `format`.

"""
import datetime as dt
Expand Down Expand Up @@ -348,6 +351,14 @@ def naturalday(value: dt.date | dt.datetime, format: str = "%b %d") -> str:
if delta.days == -1:
return _("yesterday")

if weekday and 1 < delta.days <= 6:
day_name = value.strftime("%A")
return _("this %s") % day_name

if weekday and -6 <= delta.days < -1:
day_name = value.strftime("%A")
return _("last %s") % day_name

return value.strftime(format)


Expand Down
20 changes: 20 additions & 0 deletions tests/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,3 +852,23 @@ def test_time_unit() -> None:
)
def test_rounding_by_fmt(fmt: str, value: float, expected: float) -> None:
assert time._rounding_by_fmt(fmt, value) == pytest.approx(expected)


def test_naturalday_weekday() -> None:
with freeze_time("2026-08-12"): # Wednesday
today = dt.date.today()
future_day = today + dt.timedelta(days=3)
assert humanize.naturalday(future_day, weekday=True) == "this Saturday"

past_day = today - dt.timedelta(days=3)
assert humanize.naturalday(past_day, weekday=True) == "last Sunday"

assert humanize.naturalday(today, weekday=True) == "today"
assert (
humanize.naturalday(today + dt.timedelta(days=1), weekday=True)
== "tomorrow"
)
assert (
humanize.naturalday(today - dt.timedelta(days=1), weekday=True)
== "yesterday"
)