You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Android(minSdk21)24转12小时制12:00-12:59 AM/PM取值错误

问题根因

AM/PM判断错误的核心原因是源日期解析的格式符使用错误:

  • SimpleDateFormat 中小时位的两个格式符含义完全不同:
    • hh 是12小时制的小时表示,取值范围1~12,仅用于解析/输出带AM/PM的12小时制时间
    • HH 是24小时制的小时表示,取值范围0~23,你传入的源字符串是24小时制格式,所以解析用的模式必须用HH

你当前源解析用的模式是yyyy-MM-dd hh:mm:ss,解析12点的24小时制时间时,框架会默认识别为12小时制的凌晨12点,自然输出的时候就带AM标识,和预期不符。

修复方案

适配API 21+的修复代码

只需要把源解析模式的hh替换为HH即可,修复后的扩展函数如下:

fun String.formatDate(): String {
    // 源字符串是24小时制,小时位用HH
    val sourceFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
    val outputFormat = SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.US)
    return outputFormat.format(sourceFormat.parse(this)!!)
}

补充两个优化点:

  • 不要重复创建SimpleDateFormat实例,如果这个函数调用频率高,建议把两个格式实例提到外部作为静态常量复用,避免重复初始化的性能损耗
  • 注意处理解析异常,上面代码的!!是简化写法,实际生产环境建议加空判断或者异常捕获,避免非法日期格式传入导致崩溃

如果后续你升级了minSdk到26,或者接入了核心库desugaring支持Java 8+时间API,更推荐用java.time包下的类来实现,避免SimpleDateFormat的线程安全问题:

Java Time实现方案(需API26+或desugar支持)

fun String.formatDate(): String {
    val sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.US)
    val targetFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a", Locale.US)
    return LocalDateTime.parse(this, sourceFormatter).format(targetFormatter)
}

内容的提问来源于stack exchange,提问作者Suryakant Bharti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:45:11