Repository: netbox-community/netbox

Issue:
Default to ISO 8601 date format in UI and add "June 26, 2016" as tooltip
<!--
    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.

    This form is only for proposing specific new features or enhancements.
    If you have a general idea or question, please start a discussion instead:
    https://github.com/netbox-community/netbox/discussions

    NOTE: Due to an excessive backlog of feature requests, we are not currently
    accepting any proposals which significantly extend NetBox's feature scope.

    Please describe the environment in which you are running NetBox. Be sure
    that you are running an unmodified instance of the latest stable release
    before submitting a bug report.
-->
### Environment
* Python version: 3.7.3
* NetBox version: 2.10.1

<!--
    Describe in detail the new functionality you are proposing. Include any
    specific changes to work flows, data models, or the user interface.
-->
### Proposed Functionality

The current approach seems to be to use ISO 8601

```python
SHORT_DATE_FORMAT = 'Y-m-d'          # 2016-06-26
```

where the logical order matters, for example in the changelog view that is sorted by time. For "free text" dates,

```python
DATE_FORMAT = 'N j, Y'               # June 26, 2016
```

is used. I am proposing to use `SHORT_DATE_FORMAT` everywhere in the UI except in tooltips. And then augment dates as tooltip in `DATE_FORMAT`. This is because ISO 8601 is *the* standard for dates in written form. If the user ever needs to communicate a date via voice, they are expected to translate 2016-06-26 in their head or peek in the tooltip and say "June 26, 2016".

@jeremystretch commented on ISO 8601 in https://github.com/netbox-community/netbox/issues/1412#issuecomment-321318039 already so I assume there is some background to the current default. I still would like to discuss this.

<!--
    Convey an example use case for your proposed feature. Write from the
    perspective of a NetBox user who would benefit from the proposed
    functionality and describe how.
--->
### Use Case

Consistency.

<!--
    Note any changes to the database schema necessary to support the new
    feature. For example, does the proposal require adding a new model or
    field? (Not all new features require database changes.)
--->
### Database Changes

No.

<!--
    List any new dependencies on external libraries or services that this new
    feature would introduce. For example, does the proposal require the
    installation of a new Python package? (Not all new features introduce new
    dependencies.)
-->
### External Dependencies

No.


Discussion:
Depending on the language for your region this may or may not be true. For latin based languages, it is more natural to say out loud(or in his head) 26th of June 2016(in the language of choice). Depends on the intent when using the tooltip. Anyway, idea is interesting for the tootip.
Marking this as `needs owner` for anyone who wants to do the work. Please ensure that all changes are kept consistent across all objects.

> For latin based languages, it is more natural to say out loud(or in his head) 26th of June 2016(in the language of choice).

The date formats are all [configurable](https://netbox.readthedocs.io/en/stable/configuration/optional-settings/#date-and-time-formatting).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).

I am looking into this now. Not sure how far I get. I will open a PR in the best case.

Resolving patch:
diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py
--- a/netbox/extras/models/models.py
+++ b/netbox/extras/models/models.py
@@ -431,9 +431,8 @@ class Meta:
         verbose_name_plural = 'journal entries'
 
     def __str__(self):
-        created_date = timezone.localdate(self.created)
-        created_time = timezone.localtime(self.created)
-        return f"{date_format(created_date)} - {time_format(created_time)} ({self.get_kind_display()})"
+        created = timezone.localtime(self.created)
+        return f"{date_format(created, format='SHORT_DATETIME_FORMAT')} ({self.get_kind_display()})"
 
     def get_absolute_url(self):
         return reverse('extras:journalentry', args=[self.pk])
diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py
--- a/netbox/utilities/templatetags/helpers.py
+++ b/netbox/utilities/templatetags/helpers.py
@@ -4,8 +4,10 @@
 
 import yaml
 from django import template
+from django.template.defaultfilters import date
 from django.conf import settings
 from django.urls import NoReverseMatch, reverse
+from django.utils import timezone
 from django.utils.html import strip_tags
 from django.utils.safestring import mark_safe
 from markdown import markdown
@@ -151,6 +153,36 @@ def tzoffset(value):
     return datetime.datetime.now(value).strftime('%z')
 
 
+@register.filter(expects_localtime=True)
+def annotated_date(date_value):
+    """
+    Returns date as HTML span with short date format as the content and the
+    (long) date format as the title.
+    """
+    if not date_value:
+        return ''
+
+    if type(date_value) == datetime.date:
+        long_ts = date(date_value, 'DATE_FORMAT')
+        short_ts = date(date_value, 'SHORT_DATE_FORMAT')
+    else:
+        long_ts = date(date_value, 'DATETIME_FORMAT')
+        short_ts = date(date_value, 'SHORT_DATETIME_FORMAT')
+
+    span = f'<span title="{long_ts}">{short_ts}</span>'
+
+    return mark_safe(span)
+
+
+@register.simple_tag
+def annotated_now():
+    """
+    Returns the current date piped through the annotated_date filter.
+    """
+    tzinfo = timezone.get_current_timezone() if settings.USE_TZ else None
+    return annotated_date(datetime.datetime.now(tz=tzinfo))
+
+
 @register.filter()
 def fgcolor(value):
     """


Test patch: