diff --git a/app/src/main/java/com/placeholder/ringhealth/core/common/Formatters.kt b/app/src/main/java/com/placeholder/ringhealth/core/common/Formatters.kt new file mode 100644 index 0000000..776d2dc --- /dev/null +++ b/app/src/main/java/com/placeholder/ringhealth/core/common/Formatters.kt @@ -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 +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f9a56a6..fa4e8ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,9 @@ RingHealth + + 放松 + 正常 + 中等 + 偏高 diff --git a/app/src/test/java/com/placeholder/ringhealth/core/common/FormattersTest.kt b/app/src/test/java/com/placeholder/ringhealth/core/common/FormattersTest.kt new file mode 100644 index 0000000..05a1b00 --- /dev/null +++ b/app/src/test/java/com/placeholder/ringhealth/core/common/FormattersTest.kt @@ -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)) + } +}