Page MenuHomeWildfire Games

Add translation comments and context for datetime formats
Needs ReviewPublic

Authored by temple on Aug 18 2017, 1:18 AM.

Details

Reviewers
elexis
Summary

Currently there's no direction for translators for strings like "yyyy-MM" or "HH:mm". As a result, we get translations like this:

18:12:27 brian@brian-MCP6P3:~/0ad/binaries/data/mods/public/l10n$ grep "msgid \"yyyy-MM\"" * -A1 | grep -v "^\-" | grep -v "\"\"" | grep -v "\"yyyy-MM\""
ar.public-gui-other.po-msgstr "MM/yyyy"
br.public-gui-other.po-msgstr "MM-yyyy"
ca.public-gui-other.po-msgstr "aaaa-MM"
cs.public-gui-other.po-msgstr "rrrr-MM"
de.public-gui-other.po-msgstr "MM yyyy"
eu.public-gui-other.po-msgstr "uuuu-HH"
fi.public-gui-other.po-msgstr "vvvv-KK"
fr.public-gui-other.po-msgstr "MM-yyyy"
hu.public-gui-other.po-msgstr "éééé-HH"
it.public-gui-other.po-msgstr "aaaa-MM"
lv.public-gui-other.po-msgstr "MM.yyyy"
nb.public-gui-other.po-msgstr "åååå-MM"
nl.public-gui-other.po-msgstr "MM-yyyy"
pt_BR.public-gui-other.po-msgstr "aaaa-MM"
tr.public-gui-other.po-msgstr "yyyy-AA"
uk.public-gui-other.po-msgstr "рррр-ММ"

Six of these are fine, they just rearrange MM and yyyy, but the others probably don't do what the translators intended. Here's another example:

18:12:53 brian@brian-MCP6P3:~/0ad/binaries/data/mods/public/l10n$ grep "msgid \"HH:mm\"" * -A1 | grep -v "^\-" | grep -v "\"\"" | grep -v "\"HH:mm\""
el.public-gui-ingame.po-msgstr "ΩΩ:λλ"
el.public-gui-lobby.po-msgstr "ΩΩ:λλ"
fi.public-gui-gamesetup.po-msgstr "TT:mm"
fi.public-gui-ingame.po-msgstr "TT:mm"
fi.public-gui-lobby.po-msgstr "TT:mm"
ga.public-gui-lobby.po-msgstr "UU:nn"
ko.public-gui-lobby.po-msgstr "시간:분"
pt_PT.public-gui-lobby.po-msgstr "HH:mm "
ro.public-gui-lobby.po-msgstr "OO:mm"
tr.public-gui-gamesetup.po-msgstr "SS:dd"
tr.public-gui-ingame.po-msgstr "SS:dd"
tr.public-gui-lobby.po-msgstr "SS:dd"
uk.public-gui-lobby.po-msgstr "ГГ:хх"

In each translation comment I've given an explanation of what the format is used for along with a link to a site that explains the symbols.

These are the instances I found:

  • Chat timestamp. This occurs in three separate places (lobby, game setup, session), so I've combined all three into one function.
  • Game start time, in the lobby when you have a game selected.
  • Time elapsed/remaining counters, for the game duration (replay, load, session, summary) and ceasefire, wonder-victory, etc. countdowns. The production queue had been using something separate because I didn't want to show extra zeros, e.g. 01:00 if there's one minute of training time remaining. But actually I don't see any reason why the others would want the extra zero either, so I've changed the format from "mm:ss" to "m:ss" (meaning use two digits only if you need two digits). Similarly, if the time is over an hour it will now only show one digit for the hour rather than two.
  • Game dates in the load game menu and save game dialog.
  • Game dates in the replay menu.
  • Month filter in the replay menu.
Test Plan

Check that I haven't missed any other datetime translations.
Agree with the "mm:ss" to "m:ss" change.

Diff Detail

Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

temple created this revision.Aug 18 2017, 1:18 AM
elexis added a subscriber: elexis.Aug 18 2017, 3:11 PM
elexis added inline comments.
binaries/data/mods/public/gui/common/functions_utility.js
123

This function is currently used in three cases:

  1. matchtime elapsed (replay, savegame, lobby, summary)
  2. ceasefire countdown (diplomacy screen, overlay)
  3. ingame notification countdown (f.e. wonder victory, relic victory, extinct volcano countdown)

I don't know if people on transifex would want to use two different strings (elapsed, countdown) if they knew about the string mechanics to begin with.
Nor do I know whether they would like to distinguish even further.

But the name timeToString indiciates to the programmer that he can always use this when passing a time.

Perhaps a elapsedTimeString and a countdownTimeString with the context countdown format and elapsed time format might make cleaner code and transifex material?

134

"chat timestamp"

binaries/data/mods/public/gui/common/functions_utility_loadsave.js
16

"savegame format" should do

binaries/data/mods/public/gui/lobby/lobby.js
1047

Sure startTime is a Number?
Other than that looks correct to me.

binaries/data/mods/public/gui/session/messages.js
906

That seems nice to me.
(The assumption that all chat timestamps are going to use the same time format in all languages is something I expect to be true.)

binaries/data/mods/public/gui/session/selection_panels.js
622–623

perhaps

// Translation: URL stuff
translateWithContext("remaining training time", "...")

?

(Also I didn't understand your comment about doubleclicking in the lobby yesterday. refs D326)

temple added inline comments.Aug 18 2017, 6:03 PM
binaries/data/mods/public/gui/common/functions_utility.js
123

Yes, we should be clearer here that this is a duration rather than a time like "one o'clock".

I guess it's possible that in different places we'd want to show the duration differently. For example in the replay menu maybe we only want to show hours:minutes rather than seconds too. But I'm happy with the current one-size-fits-all approach.

134

Yeah, I guess I don't need to say "format" in all of these.

binaries/data/mods/public/gui/common/functions_utility_loadsave.js
16

What do you think about combining the savegame and replay strings? It seems like they should be the same format, even though currently savegame shows the seconds while replay doesn't.

temple updated this revision to Diff 3172.Aug 18 2017, 6:07 PM

In common/functions_global_object.js:

	if (Engine.ConfigDB_GetValue("user", "overlay.realtime") === "true")
		counters.push((new Date()).toLocaleTimeString());

I saw this so I thought I'd mention it. I don't know if things are fine as is, or if we'd want to use a custom translation here, or if we'd want to use Date functions instead of some of the other translations.
(There's no US locale? So that's why I see this as 14:00:00 rather than 2:00:00 PM?)

elexis edited edge metadata.Aug 20 2017, 12:49 PM
In D795#31780, @temple wrote:

In common/functions_global_object.js:

	if (Engine.ConfigDB_GetValue("user", "overlay.realtime") === "true")
		counters.push((new Date()).toLocaleTimeString());

Yeah this looks broken.

(If you ever want to use blame to find out in which revision it was introduced, don't use svn blame, nor git blame, nor the trac interface but the phabricator interface, as one only needs one click to skip to the previous revision of that line.
https://code.wildfiregames.com/source/0ad/browse/ps/trunk/binaries/data/mods/public/gui/common/functions_global_object.js?view=blame
Looks like many people touched this line without noticing. Originally added by rP15630.)

There's no US locale? So that's why I see this as 14:00:00 rather than 2:00:00 PM

Uh this sounds a lot like a bug and should be fixed.
Said FormatMillisecondsIntoDateStringLocal function calls into L10n.cpp which uses the locale set from the config, see ReevaluateCurrentLocaleAndReload().
Thanks for the catch!

binaries/data/mods/public/gui/common/functions_utility.js
123

Ok to keep it.

130

Would be nice if it could become [%(time)s] so that the translation folks don't have to take care of escaping it (and don't need to understand why there are those backslashes to begin with).

But that will need an escapeText call to compensate and warn(escapeText(escapeText("[asd]"))); shows \\\[asd], so we'd have to ensure that either nothing calling this function adds another escapeText, or add the escapeText in every caller. Or leave as is. Pick your poison.

134

(when you enable it in the options page). were unneeded

binaries/data/mods/public/gui/common/functions_utility_loadsave.js
16

(It's more realistic to write 2 savegames withing the same minute than starting 2 matches in the same minute.)
(For the replay-menu we also run into the 1024x768 limitation (already seems to be broken by some pixels).
(Also I'd be really annoyed to see so many seconds when I don't care about that figure at all.)
We can remove the seconds from the savegame timestamp, as the user can sort by date anyhow.

So unifying the timestamp formats and removing the seconds is good to me.

So basically we have a date format where only the time matters and a date format where both time and day matter.

l10n.js sounds like a cleaner place to add all these functions (duration format, time of day format, datetime format). Actually I wonder whether it's realistic that people would want to differentiate the chat timestamp from the time-of-the-day timestamp. (HH vs H maybe?)

(I don't see a use case where l10n would use FormatMillisecondsIntoDateStringGMT rather than FormatMillisecondsIntoDateStringLocal (GMT only used to avoid applying the timezone difference to durations)).

temple updated this revision to Diff 3731.Sep 20 2017, 9:38 PM
temple added a subscriber: leper.

Moved the time/date functions to l10n.js.

Used timeOfDayToString() in the realtime overlay in functions_global_object.js, which means I had to add l10n.js everywhere that's used, which is nearly everywhere. (I suppose we could add the l10n stuff to functions_global_object instead, but I don't know if that's the best solution.)

Used the US time/date formats as default, which might annoy translators, but what can you do...

temple updated this revision to Diff 3733.Sep 20 2017, 10:58 PM

Added escape text for the chat timestamp prefix. Actually no translation currently changes it, besides a Ukrainian newline:

uk.public-gui-ingame.po:msgid "\\[%(time)s]"
uk.public-gui-ingame.po:msgstr "\n\\[%(time)s]"

But maybe that's because the \\ look scary. (Do we want them to be able to add newlines?)

I would prefer implementing D367 rather than having the monthToString() function.

temple updated this revision to Diff 3783.Sep 27 2017, 8:44 PM

fix a couple rebase mistakes

temple updated this revision to Diff 4319.Nov 22 2017, 6:32 AM

Putting the US time/date default formats into a separate patch.

Still would like to get rid of monthToString but that too should be a separate patch.

In D795#41658, @temple wrote:

Putting the US time/date default formats into a separate patch.

One could also declare the default US-international or something with US spelling and sane units. (Case in point being distances and such using meters in the game.)

Still would like to get rid of monthToString but that too should be a separate patch.

I'm not sure why that even exists, but seeing that it is just used in the replay menu I'll leave that to others.

binaries/data/mods/public/gui/common/l10n.js
6

I know you just moved this, then added a few more links, but why not link to the official docs?

http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table

In D795#41709, @leper wrote:
In D795#41658, @temple wrote:

Putting the US time/date default formats into a separate patch.

One could also declare the default US-international or something with US spelling and sane units. (Case in point being distances and such using meters in the game.)

"English (United Kingdom)" is one of the languages on Transifex, that's why it's "meters" and not "metres".
Personally, I can never get used to seeing times like 13:55:05. (Dates like 2017-11-22 aren't quite as bad.)
Since there's no "American" on Transifex, it seems like the default should use times like 1:55 pm instead (US date format too), unless you have another solution.

(I had another idea at http://irclogs.wildfiregames.com/2017-08-20-QuakeNet-%230ad-dev.log starting at 19:45, but the problem with that is not all locales have the date and time patterns defined, or defined correctly, whereas with Transifex some translator has actually looked at and hopefully thought about the format.)

Putting the US time/date default formats into a separate patch.

One could also declare the default US-international or something with US spelling and sane units. (Case in point being distances and such using meters in the game.)

"English (United Kingdom)" is one of the languages on Transifex, that's why it's "meters" and not "metres".

Which is why some sort of US-international would make sense. Note that it is meters not yards or something similarly strange.

Since there's no "American" on Transifex, it seems like the default should use times like 1:55 pm instead (US date format too), unless you have another solution.

I guess having some en_US there might solve this nicer than making the default have that, at least I'll not make that change, if you find someone that will and sees the possible confusion for most (all?) other translations as worth it, I'll not complain.

(I had another idea at http://irclogs.wildfiregames.com/2017-08-20-QuakeNet-%230ad-dev.log starting at 19:45, but the problem with that is not all locales have the date and time patterns defined, or defined correctly, whereas with Transifex some translator has actually looked at and hopefully thought about the format.)

Well, that assumes that all those actually are dates as opposed to durations. Which isn't the case for a lot of the things they are used for.

In D795#41717, @leper wrote:

Since there's no "American" on Transifex, it seems like the default should use times like 1:55 pm instead (US date format too), unless you have another solution.

I guess having some en_US there might solve this nicer than making the default have that, at least I'll not make that change, if you find someone that will and sees the possible confusion for most (all?) other translations as worth it, I'll not complain.

I'd be happy with an en_US, which would basically only touch the time/date formats (so that we don't cause headaches for the translators). But right now in the language selection it already says language = English (United States) and locale = en_US, at least for me. How does one go about adding en_US to Transifex and making the default language = English (International) and locale = en_something-else (or just en)?

I'd be happy with an en_US, which would basically only touch the time/date formats (so that we don't cause headaches for the translators). But right now in the language selection it already says language = English (United States) and locale = en_US, at least for me. How does one go about adding en_US to Transifex and making the default language = English (International) and locale = en_something-else (or just en)?

Should probably just be en, might need a few changes (source/i18n, possibly some scripts, maybe some change on transifex) in a few places.

elexis added a comment.Dec 5 2017, 6:51 PM

All XML diffs can be dropped following D619 luckily.
I wanted to ask if I could play the lazy-card and have this diff split in some smallers, (like one function+calls per patch?)

temple marked an inline comment as done.Dec 5 2017, 7:01 PM
In D795#44273, @elexis wrote:

I wanted to ask if I could play the lazy-card and have this diff split in some smallers, (like one function+calls per patch?)

Sure.

elexis added inline comments.Dec 5 2017, 7:05 PM
binaries/data/mods/public/gui/common/functions_utility.js
118

I would prefer to kill this file due to a lack of definition which files it should contain.
How about moving it to gui/common/l10n.js as well?
(There are some other random translation functions, perhaps they should be moved there eventually too)

temple added a comment.Dec 7 2017, 6:08 AM

Split into D1116, D1117, and D1118.