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
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Unreleased
----------

- Correct past and future directions for datetime values in
`format_timedelta(..., add_direction=True)` and the `timedeltaformat` filter.

v3.1.0
------

Expand Down
9 changes: 6 additions & 3 deletions flask_babel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,17 @@ def format_timedelta(
add_direction=False,
threshold=0.85,
):
"""Format the elapsed time from the given date to now or the given
timedelta.
"""Format the time between now and the given date or the given timedelta.

With ``add_direction=True``, future dates and positive timedeltas use
wording such as "in 1 hour"; past dates and negative timedeltas use
"1 hour ago".

This function is also available in the template context as filter
named `timedeltaformat`.
"""
if isinstance(datetime_or_timedelta, datetime):
datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta
datetime_or_timedelta = datetime_or_timedelta - datetime.utcnow()
return dates.format_timedelta(
datetime_or_timedelta,
granularity,
Expand Down
27 changes: 27 additions & 0 deletions tests/test_date_formatting.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
from datetime import datetime, timedelta

import flask
import pytest

import flask_babel as babel
from flask_babel import get_babel


@pytest.mark.parametrize("hours, expected", [(-1, "1 hour ago"), (1, "in 1 hour")])
@pytest.mark.parametrize("use_datetime", [True, False])
def test_timedelta_direction(monkeypatch, hours, expected, use_datetime):
class FixedDatetime(datetime):
@classmethod
def utcnow(cls):
return cls(2026, 1, 1, 12)

monkeypatch.setattr(babel, "datetime", FixedDatetime)
app = flask.Flask(__name__)
babel.Babel(app)
value = timedelta(hours=hours)
if use_datetime:
value = FixedDatetime.utcnow() + value

with app.test_request_context():
assert babel.format_timedelta(value, add_direction=True) == expected
assert (
flask.render_template_string(
"{{ value|timedeltaformat(add_direction=True) }}", value=value
)
== expected
)
assert babel.format_timedelta(value) == "1 hour"


def test_basics():
app = flask.Flask(__name__)
babel.Babel(app)
Expand Down