Page MenuHomePhabricator

MWTimestamp::getHumanTimestamp() unlocalizable
Closed, ResolvedPublic


Some time ago, I pointed out at [1] that the [[MediaWiki:Ago]] message is untranslatable and should not be used. Some time after that, a nice human-readable timestamp system was implemented [2], however, after a lot of bikeshedding talk [3], the change was reverted. Currently, MediaWiki does not have a useful implementation of human-readable timestamps, but it still has a broken implementation of those in MWTimestamp::getHumanTimestamp(), which is slowly getting used in various places.

A short summary of the problems with the current implementation:

In flective languages, you cannot use a single piece of text (e.g. “$1 seconds”) both in a sentence like “It took $1 to render the image.”, and in a sentence like “The image was rendered $1 ago.” E.g. in Czech, the first use (duration) needs nominative case, while the second use (time ago) needs instrumental case: Something took “5 _sekund_”, but it happened “před 5 _sekundami_”. Therefore, the ago message cannot use the basic messages for time units (seconds, minutes, ...), it needs separate versions of those. Also, note that while some of those messages were used in MediaWiki for a long time, some of those newly appeared for these “ago” uses, and have even been _documented_ as “Part of variable $1 in {{msg-mw|Ago}}”! Which makes it a complete mess; the current Czech translation uses instrumental for half of these messages, and nominative for the other half of them.

Another problem is the current structure/placement of the formatting code: It is placed in the language-independent MWTimestamp class, and supposedly returns a language-independent Message instance, as is assumed in its unit test, where code like

$timestamp->getHumanTimestamp()->inLanguage( 'en' )->text()

is used. It seems nice until you figure that it cannot work. Try replacing it with e.g.

$timestamp->getHumanTimestamp()->inLanguage( 'cs' )->text()

and you’ll get something like “před 3 hours”, i.e. the “ago” message is “inLanguage( 'cs' )”, but the inner $1 has already been replaced with a non-inLanguaged “hours” message in the default wiki language (!). The point is the method should reside inside Language just like e.g. formatTimePeriod (and like it was in [2]), and, if it is placed elsewhere, it needs to get the language as an argument. (I would be able to imagine the Message class having a slightly more powerful API with a “deep knowledge” of parameters, and being able to apply inLanguage recursively on them, but I think that would be a bit overcomplicated.)


Version: 1.21.x
Severity: minor
Whiteboard: aklapper-moreinfo



Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 1:24 AM
bzimport set Reference to bz45385.
bzimport added a subscriber: Unknown Object (MLST).

A minimal set of changes to allow localization of the human-readable timestamp committed to Gerrit as I7a101a083e0052a6ba07e4e54baad670e3107ab8

Mormegil: Can you answer comment 2?

(In reply to comment #2)

is this now fixed by

Yes, I believe the main issue was fixed. I would only recommend to remove the 'ago' message completely, as it is unusable (and unused now, I hope; the core seems not to use it at all, I am not sure how can I check all extensions easily).

Anyway, marking this as fixed.