Skip to content

i18n: add Dutch localization (Android) - #2865

Open
Lukasjoosten wants to merge 1 commit into
ryanbr:mainfrom
Lukasjoosten:i18n/dutch-android
Open

Lukasjoosten wants to merge 1 commit into
ryanbr:mainfrom
Lukasjoosten:i18n/dutch-android

Conversation

@Lukasjoosten

Copy link
Copy Markdown

Adds Dutch (nl) as a complete, selectable language on Android, following the shape of the Italian localization (#2454). The Apple catalogs (Strand, StrandDesign, watch targets) follow in a separate PR, to keep this one to a single platform.

Refs #2864

What changes

  • android/app/src/main/res/values-nl/strings.xml and values-nl/steps_view.xml (new locale)
  • AppLanguage gains DUTCH("nl", "Nederlands"), plus dutchCatalogTagIsSupported in AppLanguageTest
  • Tools/appchangelog-gen.py registers values-nl in LOCALE_DIRS (test_locale_dirs_match_the_res_directories fails without it)
  • Tools/i18n_echo_baseline.txt gains values-nl … nl 28

Dutch uses Latin digits and the Gregorian calendar, so the default-locale parser and formatter caveat on AppLanguage does not apply beyond what de/it already exercise.

Verification

  • Key parity with English in both directions: 2744 strings (including the ground_truth_marker_now_button id every other locale also carries), 21 plurals, 23 steps_view strings and 1 string-array. No ExtraTranslation exposure.
  • Placeholders and newlines: placeholder sets and literal \n and newline counts identical for every string and both quantities of every plural. Plural quantities are one/other.
  • Apostrophes: all 23 escaped. No bare &, and both files are well-formed XML.
  • Echo baseline: recomputed with the audit's own predicate, it gives 28 for values-nl. The same computation gives the recorded 26 for values-it. Every entry is a brand name, a metric abbreviation, an internal design-token id or a proper name (breathing-protocol and feature names).
  • Tools/i18n_audit.py --ci upstream/main: no new English-only translations and no gap for values-nl.
  • ./gradlew lintVitalFullRelease: no issues found.
  • ./gradlew testFullDebugUnitTest: AppLanguageTest passes 6/6, including the new test. This was run on a local Windows machine. Some suites only fail there and fail identically on a clean upstream/main checkout: date and number formatting under a Dutch JVM default locale, WhoopDatabaseUpgradeTest temp-file locking, and StrapLogArchiveTest. CI's Linux runner is the authoritative run.

Terminology

Translated against a fixed glossary in standard Dutch, informal je:

English Dutch
Charge · Effort · Rest (NOOP scores) Lading · Inspanning · Rust
Recovery · Strain (WHOOP terms) Herstel · Belasting
Readiness Gereedheid
Strap Bandje
Offload · Sync · Pair Ophalen · Synchroniseren · Koppelen
Resting HR · HR zones Rusthartslag · Hartslagzones
Sleep debt · Nap Slaaptekort · Dutje

The translations are machine-assisted against that glossary and were reviewed by a native Dutch speaker (the PR author).

🤖 Generated with Claude Code

Adds Dutch as a complete, selectable language on Android, following the
shape of the Italian localization (ryanbr#2454). The Apple catalogs follow in a
separate PR.

Android gains `values-nl/strings.xml` and `values-nl/steps_view.xml`.
`AppLanguage` gains the `DUTCH("nl", "Nederlands")` case and a test, and
`appchangelog-gen.py` registers `values-nl` in `LOCALE_DIRS`.

Verified:

- key sets match English in both directions across 2744 strings (including
  the `ground_truth_marker_now_button` id every locale carries), 21 plurals,
  23 `steps_view` strings and 1 string-array, so there is no
  `ExtraTranslation` exposure; `lintVitalFullRelease` reports no issues
- placeholder sets and literal newline counts identical for every string and
  both quantities of every plural; plural quantities are `one`/`other`
- all 23 apostrophes escaped
- the Android echo count recomputed with the audit's own predicate comes out
  at 28 for `values-nl` (the same computation gives the recorded 26 for
  `values-it`); every entry is a brand name, a metric abbreviation, an
  internal design-token id or a proper name

Terminology follows a fixed glossary: NOOP's own scores are Lading /
Inspanning / Rust, kept distinct from WHOOP's Herstel / Belasting, with
informal "je" throughout. The translations were machine-assisted against
that glossary and reviewed by a native Dutch speaker.

Refs ryanbr#2864

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant