Repository: pypi/warehouse

Issue:
Display how long ago the release was made
We'll want to display how long ago the release was made on the project/release detail page. Probably we'll want to implement this in javascript?



Discussion:
@dstufft I also want to make sure that we are consistent in the way that we display dates across all pages.  So, something like "April 10th, 2015"??  I prefer to avoid "4/10/15" as a format, as (unless we enable internationalisation) this means 4th October here...

It would also be cool if we could do something similar to https://docs.djangoproject.com/en/dev/ref/contrib/humanize/#naturaltime

Right now all dates are displayed using a filter that does localization (though it only supports en-us right now I think). Anything that isn't "static" should be done via javascript (e.g. April 10th, 2015 is static, it's always going to be april 10th, 2015 but '6 months ago' is dynamic, in 6 more months it's going to be '12 months ago').

Whatever we do though, it should handle localization and translation.


Resolving patch:
diff --git a/warehouse/i18n/__init__.py b/warehouse/i18n/__init__.py
--- a/warehouse/i18n/__init__.py
+++ b/warehouse/i18n/__init__.py
@@ -53,6 +53,10 @@ def includeme(config):
     # Register our i18n/l10n filters for Jinja2
     filters = config.get_settings().setdefault("jinja2.filters", {})
     filters.setdefault("format_date", "warehouse.i18n.filters:format_date")
+    filters.setdefault(
+        "format_datetime",
+        "warehouse.i18n.filters:format_datetime",
+    )
 
     # Register our finalize function for Jinja2
     config.get_settings()["jinja2.finalize"] = translate_value
diff --git a/warehouse/i18n/filters.py b/warehouse/i18n/filters.py
--- a/warehouse/i18n/filters.py
+++ b/warehouse/i18n/filters.py
@@ -21,3 +21,10 @@ def format_date(ctx, *args, **kwargs):
     request = ctx.get("request") or get_current_request()
     kwargs.setdefault("locale", request.locale)
     return babel.dates.format_date(*args, **kwargs)
+
+
+@jinja2.contextfilter
+def format_datetime(ctx, *args, **kwargs):
+    request = ctx.get("request") or get_current_request()
+    kwargs.setdefault("locale", request.locale)
+    return babel.dates.format_datetime(*args, **kwargs)


Test patch:
diff --git a/tests/unit/i18n/test_filters.py b/tests/unit/i18n/test_filters.py
--- a/tests/unit/i18n/test_filters.py
+++ b/tests/unit/i18n/test_filters.py
@@ -31,3 +31,20 @@ def test_format_date(monkeypatch):
 
     kwargs.update({"locale": request.locale})
     assert format_date.calls == [pretend.call(*args, **kwargs)]
+
+
+def test_format_datetime(monkeypatch):
+    formatted = pretend.stub()
+    format_datetime = pretend.call_recorder(lambda *a, **kw: formatted)
+    monkeypatch.setattr(babel.dates, "format_datetime", format_datetime)
+
+    request = pretend.stub(locale=pretend.stub())
+    ctx = pretend.stub(get=pretend.call_recorder(lambda k: request))
+
+    args = [pretend.stub(), pretend.stub()]
+    kwargs = {"foo": pretend.stub()}
+
+    assert filters.format_datetime(ctx, *args, **kwargs) is formatted
+
+    kwargs.update({"locale": request.locale})
+    assert format_datetime.calls == [pretend.call(*args, **kwargs)]
diff --git a/tests/unit/i18n/test_init.py b/tests/unit/i18n/test_init.py
--- a/tests/unit/i18n/test_init.py
+++ b/tests/unit/i18n/test_init.py
@@ -58,6 +58,7 @@ def test_includeme():
     assert config_settings == {
         "jinja2.filters": {
             "format_date": "warehouse.i18n.filters:format_date",
+            "format_datetime": "warehouse.i18n.filters:format_datetime",
         },
         "jinja2.finalize": i18n.translate_value,
         "jinja2.i18n.domain": "warehouse",