Repository: pypi/warehouse

Issue:
Add actual date and time to 'timeago' dates
As per feedback here:

Right now, we display a humanized version of the date / time.  

As per feedback here: https://github.com/pypa/warehouse/pull/4402#issuecomment-410383106

> sometimes, I forget when I have released my package since I have 40+ packages. So I resorted to look at pypi for more info. However, github releases and pypi at moment both love moment.js and also give some time ago. Still I could not find the exact date when a version is released.

For this, I think we should add a tooltip that shows *on hover*, e.g.

![screenshot from 2018-11-18 15-14-36](https://user-images.githubusercontent.com/3323703/48674475-b3b3ab00-eb44-11e8-9c7c-6501914206b6.png)

The datetime in the tooltip should follow an international format, e.g `YYYY-MM-DD hh:mm`

this would also solve https://github.com/pypa/warehouse/issues/3010 by providing both a "human friendly" format and technical format.

---

**Good First Issue**: This issue is good for first time contributors. If you've already contributed to Warehouse, work on [another issue without this label](https://github.com/pypa/warehouse/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+-label%3A%22good+first+issue%22) instead. If there is not a corresponding pull request for this issue, it is up for grabs. For directions for getting set up, see our [Getting Started Guide](https://warehouse.pypa.io/development/getting-started/). If you are working on this issue and have questions, feel free to ask them here, [`#pypa-dev` on Freenode](https://webchat.freenode.net/?channels=%23pypa-dev), or the [pypa-dev mailing list](https://groups.google.com/forum/#!forum/pypa-dev).

**Screenshot Required**: Please include a screenshot of your update. This helps our team give you feedback faster.



Discussion:
Hi! This is my first time contributing to warehouse and I'd like to work on this issue.
I couldn't find any project with very recent release history in the dev environment hence there is no "4 min ago" or "about 4 hours ago".
**Screenshot:**
![tooltip](https://user-images.githubusercontent.com/20538494/50300685-2947c980-04ab-11e9-88fa-79cf650cc6eb.jpg)

Hey @darkHarry, thanks for working on this. Indeed, the packages in the dev environment will be a few weeks old. You'll need to either:

* manually change the creation date of an existing package via [the interactive shell](https://warehouse.pypa.io/development/getting-started/?highlight=shell#running-the-interactive-shell)
* [upload a new package to your development instance with `twine`](https://warehouse.pypa.io/development/reviewing-patches/?highlight=twine#testing-with-twine)

Let us know if you have any issues with either of these.
(Also, it would be great to include a time zone with the full datetime as well!)
I just checked the Project's release created datetime object and it's tzinfo (time zone info) attribute is None. So, I don't see any way to fetch the time zone. Any other place to look for it?
Pretty sure we store everything in the database using UTC.
Hi @dstufft, so should I add "_UTC_" or "_00:00_" in the date time tooltip? Tell me if I'm missing something : )

Resolving patch:
diff --git a/warehouse/config.py b/warehouse/config.py
--- a/warehouse/config.py
+++ b/warehouse/config.py
@@ -280,6 +280,7 @@ def configure(settings=None):
     filters.setdefault("contains_valid_uris", "warehouse.filters:contains_valid_uris")
     filters.setdefault("format_package_type", "warehouse.filters:format_package_type")
     filters.setdefault("parse_version", "warehouse.filters:parse_version")
+    filters.setdefault("localize_datetime", "warehouse.filters:localize_datetime")
 
     # We also want to register some global functions for Jinja
     jglobals = config.get_settings().setdefault("jinja2.globals", {})
diff --git a/warehouse/filters.py b/warehouse/filters.py
--- a/warehouse/filters.py
+++ b/warehouse/filters.py
@@ -23,6 +23,7 @@
 import html5lib.treewalkers
 import jinja2
 import packaging.version
+import pytz
 
 from pyramid.threadlocal import get_current_request
 
@@ -154,5 +155,9 @@ def parse_version(version_str):
     return packaging.version.parse(version_str)
 
 
+def localize_datetime(timestamp):
+    return pytz.utc.localize(timestamp)
+
+
 def includeme(config):
     config.add_request_method(_camo_url, name="camo_url")


Test patch:
diff --git a/tests/functional/test_templates.py b/tests/functional/test_templates.py
--- a/tests/functional/test_templates.py
+++ b/tests/functional/test_templates.py
@@ -48,6 +48,7 @@ def test_templates_for_empty_titles():
             "contains_valid_uris": "warehouse.filters:contains_valid_uris",
             "format_package_type": "warehouse.filters:format_package_type",
             "parse_version": "warehouse.filters:parse_version",
+            "localize_datetime": "warehouse.filters:localize_datetime",
         }
     )
 
diff --git a/tests/unit/test_filters.py b/tests/unit/test_filters.py
--- a/tests/unit/test_filters.py
+++ b/tests/unit/test_filters.py
@@ -10,6 +10,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import datetime
 import urllib.parse
 
 from functools import partial
@@ -186,3 +187,17 @@ def test_format_package_type(inp, expected):
 )
 def test_parse_version(inp, expected):
     assert filters.parse_version(inp) == expected
+
+
+@pytest.mark.parametrize(
+    ("inp", "expected"),
+    [
+        (
+            datetime.datetime(2018, 12, 26, 13, 36, 5, 789013),
+            "2018-12-26 13:36:05.789013 UTC",
+        )
+    ],
+)
+def test_localize_datetime(inp, expected):
+    datetime_format = "%Y-%m-%d %H:%M:%S.%f %Z"
+    assert filters.localize_datetime(inp).strftime(datetime_format) == expected