Humanize naturaltime alternative phrasing

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Humanize naturaltime alternative phrasing

Gregory Kaleka
Django Humanize's naturaltime filter currently uses the phrasing "5 hours from now". In some contexts, I find the phrasing "in 5 hours" more natural.

Here's a diff in the naturaltime definition that would allow this alternative phrasing as an option. Any thoughts from the community on this?

Also, where are the unittests for the humanize filters? I couldn't readily find them.

Thanks all!


@@ -209,10 +209,12 @@ def naturalday(value, arg=None):
 
# This filter doesn't require expects_localtime=True because it deals properly
 
# with both naive and aware datetimes. Therefore avoid the cost of conversion.
 
@register.filter
-def naturaltime(value):
+def naturaltime(value, use_in_phrasing=False):
     
"""
     For date and time values show how many seconds, minutes, or hours ago
-    compared to current timestamp return representing string.
+    compared to current timestamp return representing string. If use_in_phrasing
+    is True, returns a string like 'in 5 hours' for future times, rather than
+    '5 hours from now'.
     """

     
if not isinstance(value, date):  # datetime is a subclass of date
         
return value
@@ -271,22 +273,45 @@ def naturaltime(value):
         
elif delta.seconds == 0:
             
return _('now')
         
elif delta.seconds < 60:
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a second from now', '%(count)s seconds from now', delta.seconds
-            ) % {'count': delta.seconds}
+            if use_in_phrasing:
+                # Note 'in a second' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 second', 'in %(count)s seconds', delta.seconds
+                ) % {'count': delta.seconds}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a second from now', '%(count)s seconds from now', delta.seconds
+                ) % {'count': delta.seconds}
         
elif delta.seconds // 60 < 60:
             count
= delta.seconds // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a minute from now', '%(count)s minutes from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                # Note 'in a minute' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 minute', 'in %(count)s minutes', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a minute from now', '%(count)s minutes from now', count
+                ) % {'count': count}
         
else:
             count
= delta.seconds // 60 // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'an hour from now', '%(count)s hours from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in an hour', 'in %(count)s hours', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'an hour from now', '%(count)s hours from now', count
+                ) % {'count': count}

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ea7eb308-abac-4a37-8e31-c6d862729949%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Humanize naturaltime alternative phrasing

Adam Johnson-2
Hi Gregory,

I'm no expert on making changes to filters like this, but do you know what would the impact on translations be? Is there an equivalent alternative phrasing for all languages?

FYI the tests are here: https://github.com/django/django/blob/78912ccd0e1fcdfe98ca85081c9eb8acb7aa1f6d/tests/humanize_tests/tests.py#L181 . I found them by grepping the codebase for "a second from now".

Adam

On Fri, 1 Jun 2018 at 17:40, Gregory Kaleka <[hidden email]> wrote:
Django Humanize's naturaltime filter currently uses the phrasing "5 hours from now". In some contexts, I find the phrasing "in 5 hours" more natural.

Here's a diff in the naturaltime definition that would allow this alternative phrasing as an option. Any thoughts from the community on this?

Also, where are the unittests for the humanize filters? I couldn't readily find them.

Thanks all!


@@ -209,10 +209,12 @@ def naturalday(value, arg=None):
 
# This filter doesn't require expects_localtime=True because it deals properly
 
# with both naive and aware datetimes. Therefore avoid the cost of conversion.
 
@register.filter
-def naturaltime(value):
+def naturaltime(value, use_in_phrasing=False):
     
"""
     For date and time values show how many seconds, minutes, or hours ago
-    compared to current timestamp return representing string.
+    compared to current timestamp return representing string. If use_in_phrasing
+    is True, returns a string like 'in 5 hours' for future times, rather than
+    '5 hours from now'.
     """

     
if not isinstance(value, date):  # datetime is a subclass of date
         
return value
@@ -271,22 +273,45 @@ def naturaltime(value):
         
elif delta.seconds == 0:
             
return _('now')
         
elif delta.seconds < 60:
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a second from now', '%(count)s seconds from now', delta.seconds
-            ) % {'count': delta.seconds}
+            if use_in_phrasing:
+                # Note 'in a second' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 second', 'in %(count)s seconds', delta.seconds
+                ) % {'count': delta.seconds}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a second from now', '%(count)s seconds from now', delta.seconds
+                ) % {'count': delta.seconds}
         
elif delta.seconds // 60 < 60:
             count
= delta.seconds // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a minute from now', '%(count)s minutes from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                # Note 'in a minute' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 minute', 'in %(count)s minutes', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a minute from now', '%(count)s minutes from now', count
+                ) % {'count': count}
         
else:
             count
= delta.seconds // 60 // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'an hour from now', '%(count)s hours from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in an hour', 'in %(count)s hours', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'an hour from now', '%(count)s hours from now', count
+                ) % {'count': count}

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ea7eb308-abac-4a37-8e31-c6d862729949%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0tQdAbXRXhS0awv9NyfH%3D%2BmOnkfrsLBDwwKkWedOOt-A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Humanize naturaltime alternative phrasing

Gregory Kaleka
That's a great question. My guess would be that there is an equivalent in some languages but not all. It is tricky, though; French at least has both equivalent phrasings, but the localization is actually already using the phrasing that more closely matches "in five minutes."

Some translations could be identical for both phrasings (they have the same meaning after all), or if there is a meaningful equivalent, there could be separate translations. I suppose the way to start would be to copy/paste the existing translations, and allow contributors to improve translations as appropriate for each individual language.

On Sat, Jun 2, 2018 at 8:38 AM Adam Johnson <[hidden email]> wrote:
Hi Gregory,

I'm no expert on making changes to filters like this, but do you know what would the impact on translations be? Is there an equivalent alternative phrasing for all languages?

FYI the tests are here: https://github.com/django/django/blob/78912ccd0e1fcdfe98ca85081c9eb8acb7aa1f6d/tests/humanize_tests/tests.py#L181 . I found them by grepping the codebase for "a second from now".

Adam

On Fri, 1 Jun 2018 at 17:40, Gregory Kaleka <[hidden email]> wrote:
Django Humanize's naturaltime filter currently uses the phrasing "5 hours from now". In some contexts, I find the phrasing "in 5 hours" more natural.

Here's a diff in the naturaltime definition that would allow this alternative phrasing as an option. Any thoughts from the community on this?

Also, where are the unittests for the humanize filters? I couldn't readily find them.

Thanks all!


@@ -209,10 +209,12 @@ def naturalday(value, arg=None):
 
# This filter doesn't require expects_localtime=True because it deals properly
 
# with both naive and aware datetimes. Therefore avoid the cost of conversion.
 
@register.filter
-def naturaltime(value):
+def naturaltime(value, use_in_phrasing=False):
     
"""
     For date and time values show how many seconds, minutes, or hours ago
-    compared to current timestamp return representing string.
+    compared to current timestamp return representing string. If use_in_phrasing
+    is True, returns a string like 'in 5 hours' for future times, rather than
+    '5 hours from now'.
     """

     
if not isinstance(value, date):  # datetime is a subclass of date
         
return value
@@ -271,22 +273,45 @@ def naturaltime(value):
         
elif delta.seconds == 0:
             
return _('now')
         
elif delta.seconds < 60:
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a second from now', '%(count)s seconds from now', delta.seconds
-            ) % {'count': delta.seconds}
+            if use_in_phrasing:
+                # Note 'in a second' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 second', 'in %(count)s seconds', delta.seconds
+                ) % {'count': delta.seconds}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a second from now', '%(count)s seconds from now', delta.seconds
+                ) % {'count': delta.seconds}
         
elif delta.seconds // 60 < 60:
             count
= delta.seconds // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'a minute from now', '%(count)s minutes from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                # Note 'in a minute' is not used because it has an idiomatic connotation of 'about'
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in 1 minute', 'in %(count)s minutes', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'a minute from now', '%(count)s minutes from now', count
+                ) % {'count': count}
         
else:
             count
= delta.seconds // 60 // 60
-            return ngettext(
-                # Translators: please keep a non-breaking space (U+00A0)
-                # between count and time unit.
-                'an hour from now', '%(count)s hours from now', count
-            ) % {'count': count}
+            if use_in_phrasing:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'in an hour', 'in %(count)s hours', count
+                ) % {'count': count}
+            else:
+                return ngettext(
+                    # Translators: please keep a non-breaking space (U+00A0)
+                    # between count and time unit.
+                    'an hour from now', '%(count)s hours from now', count
+                ) % {'count': count}

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ea7eb308-abac-4a37-8e31-c6d862729949%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0tQdAbXRXhS0awv9NyfH%3D%2BmOnkfrsLBDwwKkWedOOt-A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CABVckaRvNgF%2BmHV2ANWLS1zCtd5GTrEz-B_nwa8tgbCzX_N64A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Humanize naturaltime alternative phrasing

Claude Paroz
I think I'd rather do some refactoring so that creating its own filter with custom strings is easier.
I played a bit with the idea and obtained that:
https://github.com/claudep/django/commit/b776f120f180

Claude

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/41d8f9b7-d44b-4907-9cb1-961fbbb13dca%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Humanize naturaltime alternative phrasing

Adam Johnson-2
Claude, that's a good idea - it increases the future options and also doesn't require a lot of translation work up in Django core up front.

On Sun, 3 Jun 2018 at 09:39, Claude Paroz <[hidden email]> wrote:
I think I'd rather do some refactoring so that creating its own filter with custom strings is easier.
I played a bit with the idea and obtained that:
https://github.com/claudep/django/commit/b776f120f180

Claude

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/41d8f9b7-d44b-4907-9cb1-961fbbb13dca%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0HFczo-jm_10qidE%3Ds3oQtwRE4W9kxZ9P8j1nVTqse3g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.