From a8c48e33a06ff80aebd975a1b28afd84dd05f095 Mon Sep 17 00:00:00 2001 From: atsunatsu Date: Tue, 4 Aug 2026 16:56:25 +0800 Subject: [PATCH] fix(i18n): localize pass date and time formats for Chinese --- .../look4sat/core/presentation/Components.kt | 7 +++++- .../look4sat/feature/passes/PassesScreen.kt | 7 +++++- .../feature/passes/PassesViewModel.kt | 22 ++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Components.kt b/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Components.kt index d95eaec3..04010d41 100644 --- a/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Components.kt +++ b/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Components.kt @@ -144,7 +144,7 @@ fun RowScope.NextPassRow(pass: OrbitalPass, modifier: Modifier = Modifier, isUtc if (isUtc) TimeZone.getTimeZone("UTC") else TimeZone.getDefault() } val sdfTime = remember(isUtc) { - SimpleDateFormat("HH:mm:ss", Locale.ENGLISH).also { it.timeZone = timeZone } + SimpleDateFormat("HH:mm:ss", displayLocale()).also { it.timeZone = timeZone } } ElevatedCard( modifier = modifier @@ -213,6 +213,11 @@ fun RowScope.NextPassRow(pass: OrbitalPass, modifier: Modifier = Modifier, isUtc } } +private fun displayLocale(): Locale { + val locale = Locale.getDefault() + return if (locale.language == Locale.CHINESE.language) locale else Locale.ENGLISH +} + @Composable fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) { ElevatedButton( diff --git a/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesScreen.kt b/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesScreen.kt index 10a75a46..b39aa06c 100644 --- a/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesScreen.kt +++ b/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesScreen.kt @@ -292,6 +292,11 @@ private fun StickyDateHeader(label: String, sunriseTime: String, sunsetTime: Str } } +private fun displayLocale(): Locale { + val locale = Locale.getDefault() + return if (locale.language == Locale.CHINESE.language) locale else Locale.ENGLISH +} + @Preview(showBackground = true) @Composable private fun DeepSpacePassPreview() { @@ -324,7 +329,7 @@ private fun PassItem( if (isUtc) TimeZone.getTimeZone("UTC") else TimeZone.getDefault() } val sdfTime = remember(isUtc) { - SimpleDateFormat("HH:mm:ss", Locale.ENGLISH).also { it.timeZone = timeZone } + SimpleDateFormat("HH:mm:ss", displayLocale()).also { it.timeZone = timeZone } } val aosTimeStr = remember(pass.aosTime, isUtc) { sdfTime.format(Date(pass.aosTime)) } val losTimeStr = remember(pass.losTime, isUtc) { sdfTime.format(Date(pass.losTime)) } diff --git a/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesViewModel.kt b/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesViewModel.kt index f8e6b230..284e7456 100644 --- a/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesViewModel.kt +++ b/feature/passes/src/main/java/com/rtbishop/look4sat/feature/passes/PassesViewModel.kt @@ -145,12 +145,28 @@ class PassesViewModel( } } + private fun displayLocale(): Locale { + val locale = Locale.getDefault() + return if (locale.language == Locale.CHINESE.language) locale else Locale.ENGLISH + } + + /** Returns the visible pass-date format. Keep non-Chinese locales identical to upstream. */ + private fun dateFormat(tz: TimeZone): SimpleDateFormat { + val locale = displayLocale() + val pattern = if (locale.language == Locale.CHINESE.language) { + "yyyy'年'M'月'd'日' EEEE" + } else { + "EEE, dd MMM yyyy" + } + return SimpleDateFormat(pattern, locale).also { it.timeZone = tz } + } + // Computes sunrise/sunset strings for each unique calendar day in the pass list, plus today for DeepSpace private fun computeSunTimes(passes: List, isUtc: Boolean): Map> { val stationPos = settingsRepo.stationPosition.value val tz = if (isUtc) TimeZone.getTimeZone("UTC") else TimeZone.getDefault() - val sdfDate = SimpleDateFormat("EEE, dd MMM yyyy", Locale.ENGLISH).also { it.timeZone = tz } - val sdfTime = SimpleDateFormat("HH:mm", Locale.ENGLISH).also { it.timeZone = tz } + val sdfDate = dateFormat(tz) + val sdfTime = SimpleDateFormat("HH:mm", displayLocale()).also { it.timeZone = tz } val result = LinkedHashMap>() // DeepSpace group always shows today's sun times if (passes.any { it.isDeepSpace }) { @@ -173,7 +189,7 @@ class PassesViewModel( private fun groupPasses(passes: List, isUtc: Boolean): Map> { val tz = if (isUtc) TimeZone.getTimeZone("UTC") else TimeZone.getDefault() - val sdfDate = SimpleDateFormat("EEE, dd MMM yyyy", Locale.ENGLISH).also { it.timeZone = tz } + val sdfDate = dateFormat(tz) val ordered = LinkedHashMap>() val deepSpace = passes.filter { it.isDeepSpace } if (deepSpace.isNotEmpty()) ordered["DeepSpace (period >225min)"] = deepSpace