[Django] #21408: Fallback to timesince produces erroneous translations in naturaltime

9 views
Skip to first unread message

Django

unread,
Nov 8, 2013, 4:22:05 PM11/8/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
------------------------------+-----------------------------------
Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: Translations | Version: 1.6
Severity: Normal | Keywords: i18n l10n translation
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+-----------------------------------
The
[[https://docs.djangoproject.com/en/dev/ref/contrib/humanize/#naturaltime|naturaltime]]
filter in `django.contrib.humanize` composes strings for days, weeks,
months, and years from the words "ago" and "in" and the output of the
built-in
[[https://docs.djangoproject.com/en/dev/ref/templates/builtins/#timesince|timesince]]
filter. See here, where `delta` is to be supplied by `timesince`:

{{{
#: templatetags/humanize.py:190
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s ago"
msgstr "vor %(delta)s"
}}}

This produces erroneous translations in German (and probably other
inflectional languages, too).

"3 days, 12 hours ago" is translated by Django as

{{{
vor 3 Tage, 12 Stunden
}}}

but the correct translation is (with dative inflection)

{{{
vor 3 Tagen, 12 Stunden
}}}

"3 Tage" is correct for `timesince`, but for `naturaltime` it must become
"3 Tagen". Unfortunately, the assumption that these translations can
simply be pieced together from translated bits in timesince.py is
mistaken.

I apologise if this isn't the right channel. I'd be glad to help, but so
far I haven't seen a good way to avoid duplicating translations.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 8, 2013, 4:33:59 PM11/8/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: i18n l10n | Needs documentation: 0
translation | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by claudep):

* needs_better_patch: => 0
* component: Translations => Internationalization
* needs_tests: => 0
* version: 1.6 => master
* needs_docs: => 0
* stage: Unreviewed => Accepted


Comment:

Surely, this will need duplication of translatable strings. One solution
would be to make the `django.utils.timesince` utility to accept a new
optional argument containing a set of translatable strings. Then,
`naturaltime` will be able to provide its own set of `npgettext_lazy`
(with context) strings.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:1>

Django

unread,
Nov 8, 2013, 5:32:45 PM11/8/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: i18n l10n | Needs documentation: 0
translation | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by 676c7473@…):

Thank you for your answer. Slightly off-topic: I noticed a minor error in
the docs for `npgettext_lazy` and have fixed it in
https://github.com/django/django/pull/1895.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:2>

Django

unread,
Nov 9, 2013, 11:46:40 AM11/9/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: i18n l10n | Needs documentation: 0
translation | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by 676c7473@…):

I'm running into some difficulties with the code and the translations.
Could it be that the .po files are out of sync with the code?

in `humanize.py`, line 204, there are bits like this one:

{{{
return ungettext(
# Translators: \\u00a0 is non-breaking space
'a second ago', '%(count)s\u00a0seconds ago', delta.seconds
) % {'count': delta.seconds}
}}}

There is a corresponding entry in the "en" locale, but in the "de" locale
it looks different:

{{{
#. Translators: \\u00a0 is non-breaking space
#: templatetags/humanize.py:198
#, python-format
msgid "a second ago"
msgid_plural "%(count)s\\u00a0seconds ago"
msgstr[0] ""
msgstr[1] ""
}}}

{{{
#: templatetags/humanize.py:196
#, python-format
msgid "a second ago"
msgid_plural "%(count)s seconds ago"
msgstr[0] "vor einer Sekunde"
msgstr[1] "vor %(count)s Sekunden"
}}}

I guess the translation is still found because the msgid is the same, but
the German translation doesn't have the non-breaking space.

Also, these gettext messages in `timesince.py`, line 24,

{{{
chunks = (
(60 * 60 * 24 * 365, ungettext_lazy('%d year', '%d years')),
(60 * 60 * 24 * 30, ungettext_lazy('%d month', '%d months')),
...
}}}

don't exist in the "de" translations. As far as I can tell, the msgid
`"year"` will not match `"%d year"`.

{{{
#: utils/timesince.py:23
#, python-format
msgid "%d year"
msgid_plural "%d years"
msgstr[0] ""
msgstr[1] ""
}}}

{{{
#: utils/timesince.py:22
msgid "year"
msgid_plural "years"
msgstr[0] "Jahr"
msgstr[1] "Jahre"
}}}

I'm not sure what's happening here. I'll experiment some more, maybe
things will become clearer soon. If you want to share some advice, please
do! Thanks.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:3>

Django

unread,
Nov 9, 2013, 12:02:45 PM11/9/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: i18n l10n | Needs documentation: 0
translation | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by claudep):

You might find more up-to-date translations in the 1.6.x branch. We've
still not updated master with the more recent translations.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:4>

Django

unread,
Nov 9, 2013, 1:17:12 PM11/9/13
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: i18n l10n | Needs documentation: 0
translation | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by 676c7473@…):

Yes, @claudep, thank you, unfortunately there are no unit tests for those,
and consequently the bug they introduced was overlooked: ticket:21415
Sorry for not noticing this earlier.

David

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:5>

Django

unread,
Feb 23, 2017, 3:21:29 AM2/23/17
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------

Reporter: 676c7473@… | Owner: nobody
Type: Bug | Status: new
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Accepted
translation |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Markus Bertheau):

Bug still exists in 1.8.

A workaround for German for intervals into the future is to manually
replace 'in' with 'noch', resulting in 'noch 2 Tage, 3 Stunden', which is
correct.

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:6>

Django

unread,
Mar 13, 2018, 10:08:51 AM3/13/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: assigned

Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Accepted
translation |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Maximilian Merz):

* status: new => assigned
* owner: nobody => Maximilian Merz


--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:7>

Django

unread,
Mar 13, 2018, 11:40:01 AM3/13/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: assigned
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Accepted
translation |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Maximilian Merz):

[https://github.com/django/django/pull/9777 pull request 9777] submitted

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:8>

Django

unread,
Mar 20, 2018, 12:29:22 PM3/20/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: assigned
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Accepted
translation |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:9>

Django

unread,
Apr 10, 2018, 11:19:36 AM4/10/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: assigned
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Accepted
translation |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:10>

Django

unread,
May 10, 2018, 8:45:01 AM5/10/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: assigned
Component: | Version: master
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n l10n | Triage Stage: Ready for
translation | checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:11>

Django

unread,
May 10, 2018, 9:55:41 AM5/10/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: closed
Component: | Version: master
Internationalization |
Severity: Normal | Resolution: fixed

Keywords: i18n l10n | Triage Stage: Ready for
translation | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz <claude@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"78912ccd0e1fcdfe98ca85081c9eb8acb7aa1f6d" 78912ccd]:
{{{
#!CommitTicketReference repository=""
revision="78912ccd0e1fcdfe98ca85081c9eb8acb7aa1f6d"
Fixed #21408 — German Translation for “3 days ago”

The problem:
“3 days ago” should translate to “vor 3 Tagen” in German, while “3 days”
translates to “3 Tage”. #21408 describes that django always translated to
“Tage”, even when the dative “Tagen” was correct. The same applies to
months (“Monate”/“Monaten”) and years (“Jahre”/“Jahren”).

The solution:
Let `timesince` caller provide the string dict to use for the time-related
strings.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:12>

Django

unread,
Sep 29, 2018, 9:06:54 AM9/29/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: closed
Component: | Version: master
Internationalization |
Severity: Normal | Resolution: fixed
Keywords: i18n l10n | Triage Stage: Ready for
translation | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Carlton Gibson <carlton.gibson@…>):

In [changeset:"ddcb9e806275114c91bbed90bc917374ba08a9ae" ddcb9e80]:
{{{
#!CommitTicketReference repository=""
revision="ddcb9e806275114c91bbed90bc917374ba08a9ae"
Refs #21408 -- Updated naturaltime translation test.

Upcoming German translations will not differ for past and future
naturaltime
translations. Using Czech language instead.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:13>

Django

unread,
Sep 29, 2018, 9:07:48 AM9/29/18
to django-...@googlegroups.com
#21408: Fallback to timesince produces erroneous translations in naturaltime
-------------------------------------+-------------------------------------
Reporter: 676c7473@… | Owner:
| Maximilian Merz
Type: Bug | Status: closed
Component: | Version: master
Internationalization |
Severity: Normal | Resolution: fixed
Keywords: i18n l10n | Triage Stage: Ready for
translation | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Carlton Gibson <carlton.gibson@…>):

In [changeset:"7b444bf5f7cd2584da0356b25622f5a6b4559273" 7b444bf]:
{{{
#!CommitTicketReference repository=""
revision="7b444bf5f7cd2584da0356b25622f5a6b4559273"
[2.1.x] Refs #21408 -- Updated naturaltime translation test.

Upcoming German translations will not differ for past and future
naturaltime
translations. Using Czech language instead.

Backport of ddcb9e806275114c91bbed90bc917374ba08a9ae from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21408#comment:14>

Reply all
Reply to author
Forward
0 new messages