Kotlin中ISO日期与当前日期对比并按规则格式化的实现(minSdk21)
解决方案
因为项目minSdk为21,低于Java8 time库要求的最低API26,优先推荐开启Android官方核心库脱糖使用现代时间API,兼容性和稳定性更优。
前置配置(开启核心库脱糖)
在module级build.gradle中添加如下配置:
android { compileOptions { // 开启核心库脱糖 coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' }
核心实现代码
import java.time.LocalDate import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.util.Locale fun formatIsoDate(isoStr: String): String { // 直接解析ISO带时区格式字符串 val targetZonedTime = ZonedDateTime.parse(isoStr) // 转换为设备当前时区后取日期,避免跨时区导致日期判断错误 val targetDate = targetZonedTime.withZoneSameInstant(java.time.ZoneId.systemDefault()).toLocalDate() val today = LocalDate.now() return if (targetDate.isEqual(today)) { // 同一天输出HH:mm格式时间 targetZonedTime.format(DateTimeFormatter.ofPattern("HH:mm")) } else { // 非同一天输出dd MMM yyyy格式日期,指定Locale可控制月份显示语言 targetZonedTime.format(DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.US)) } } // 测试调用 val date = "2021-10-01T18:39:10.0492422+01:00" val result = formatIsoDate(date)
无需脱糖的兼容方案(基于SimpleDateFormat)
如果项目不适合开启脱糖,可以用传统API实现:
import java.text.SimpleDateFormat import java.util.* fun formatIsoDateLegacy(isoStr: String): String { val isoParser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX", Locale.US) val targetDate = isoParser.parse(isoStr) ?: return "" // 对比是否为同一天 val todayCal = Calendar.getInstance() val targetCal = Calendar.getInstance() targetCal.time = targetDate val isSameDay = todayCal.get(Calendar.YEAR) == targetCal.get(Calendar.YEAR) && todayCal.get(Calendar.DAY_OF_YEAR) == targetCal.get(Calendar.DAY_OF_YEAR) return if (isSameDay) { SimpleDateFormat("HH:mm", Locale.getDefault()).format(targetDate) } else { SimpleDateFormat("dd MMM yyyy", Locale.US).format(targetDate) } }
注意事项
- 如果业务要求以输入ISO字符串的时区为准判断日期,去掉
withZoneSameInstant转换逻辑即可 - 生产环境建议添加日期解析异常捕获,避免非法格式字符串导致崩溃
- 月份显示语言可通过修改
Locale参数调整,如需跟随系统语言改为Locale.getDefault()即可
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

