feat: 新增数值格式化工具(含单元测试)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-10 10:35:33 +08:00
co-authored by Claude Code
parent ea8897f901
commit bf373a2a5a
3 changed files with 109 additions and 0 deletions
@@ -0,0 +1,55 @@
package com.placeholder.ringhealth.core.common
import androidx.annotation.StringRes
import com.placeholder.ringhealth.R
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
/** 步数:千分位,如 8,426。 */
fun formatSteps(steps: Int): String = String.format(Locale.CHINA, "%,d", steps)
/** 距离:保留两位小数(单位 km 由 UI 单独展示)。 */
fun formatDistance(km: Double): String = String.format(Locale.CHINA, "%.2f", km)
/** 卡路里:只做千分位,单位「千卡」由 UI 用字符串资源拼接(ledger Ruling R13)。 */
fun formatCalories(kcal: Int): String = String.format(Locale.CHINA, "%,d", kcal)
/** 睡眠时长:7小时32分 / 45分 / 8小时。 */
fun formatSleepDuration(minutes: Int): String {
val hours = minutes / 60
val mins = minutes % 60
return when {
hours > 0 && mins > 0 -> "${hours}小时${mins}分"
hours > 0 -> "${hours}小时"
else -> "${mins}分"
}
}
/** 运动时长:1小时05分 / 42分(分钟补零)。 */
fun formatDuration(minutes: Int): String {
val hours = minutes / 60
val mins = minutes % 60
return if (hours > 0) {
String.format(Locale.CHINA, "%d小时%02d分", hours, mins)
} else {
"${mins}分"
}
}
/** 时间戳 → HH:mm。 */
fun formatClock(timestamp: Long): String =
SimpleDateFormat("HH:mm", Locale.CHINA).format(Date(timestamp))
/** 时间戳 → yyyy-MM-dd。 */
fun formatDate(timestamp: Long): String =
SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(Date(timestamp))
/** 压力值 → 字符串资源 id。中文描述的唯一来源是 `strings.xml`(ledger Ruling R13)。 */
@StringRes
fun stressLevelLabelRes(stress: Int): Int = when {
stress < 30 -> R.string.stress_relaxed
stress < 60 -> R.string.stress_normal
stress < 80 -> R.string.stress_medium
else -> R.string.stress_high
}
+5
View File
@@ -1,4 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">RingHealth</string> <string name="app_name">RingHealth</string>
<string name="stress_relaxed">放松</string>
<string name="stress_normal">正常</string>
<string name="stress_medium">中等</string>
<string name="stress_high">偏高</string>
</resources> </resources>
@@ -0,0 +1,49 @@
package com.placeholder.ringhealth.core.common
import com.placeholder.ringhealth.R
import org.junit.Assert.assertEquals
import org.junit.Test
class FormattersTest {
@Test
fun `formatSleepDuration 处理小时与分钟`() {
assertEquals("7小时32分", formatSleepDuration(452))
assertEquals("45分", formatSleepDuration(45))
assertEquals("8小时", formatSleepDuration(480))
assertEquals("0分", formatSleepDuration(0))
}
@Test
fun `formatDuration 处理小时与分钟`() {
assertEquals("1小时05分", formatDuration(65))
assertEquals("42分", formatDuration(42))
}
@Test
fun `formatSteps 添加千分位`() {
assertEquals("8,426", formatSteps(8426))
assertEquals("0", formatSteps(0))
assertEquals("1,234,567", formatSteps(1234567))
}
@Test
fun `formatDistance 保留两位小数`() {
assertEquals("6.21", formatDistance(6.212))
assertEquals("0.00", formatDistance(0.0))
}
@Test
fun `formatCalories 只返回千分位数字`() {
assertEquals("327", formatCalories(327))
assertEquals("1,234", formatCalories(1234))
}
@Test
fun `stressLevelLabelRes 按区间映射到对应字符串资源`() {
assertEquals(R.string.stress_relaxed, stressLevelLabelRes(20))
assertEquals(R.string.stress_normal, stressLevelLabelRes(45))
assertEquals(R.string.stress_medium, stressLevelLabelRes(65))
assertEquals(R.string.stress_high, stressLevelLabelRes(90))
}
}