You need to enable JavaScript to run this app. 为何安卓TimePickerDialog选择PM后仍自动设置为AM?
优惠活动
大模型
产品
解决方案
定价
更多

为何安卓TimePickerDialog选择PM后仍自动设置为AM?

核心问题

你的bug根源是手动换算时间的过程里把上下午(AM/PM)的标记信息给丢了,错把24小时制的时间值做了无效截断,导致Calendar根本识别不到你选的是PM时段。
具体错处拆解:

  • TimePickerDialog回调的hourOfDay是0-23范围的24小时制数值,比如下午2点会返回14
  • 你拿到值后写了个逻辑:只要小时大于12就减12,把14算成2,之后直接把这个2塞给Calendar.HOUR_OF_DAY字段
  • 这个字段本来就是用来存0-23范围的24小时值的,当你传入2的时候,Calendar默认把它当成凌晨2点(AM),原来PM的时段信息在你减12的那步就已经全丢了,最后格式化出来的结果自然永远是AM。

实际复现场景:你选下午3点(PM),回调返回hourOfDay=15

  1. 原代码算出来hr=15-12=3
  2. 给Calendar的HOUR_OF_DAY赋值3,Calendar自动判定这是凌晨3点
  3. 格式化输出的就是3:00 AM,和你选PM的预期完全反过来
正确实现

根本不用自己手动做24小时制转12小时制的计算,Calendar本身就能根据传入的0-23范围的小时值,自动匹配对应的上下午标记:

  • 直接把回调返回的原始hourOfDay值传给Calendar.HOUR_OF_DAY字段
  • 保留原来的SimpleDateFormat("h:mm a")格式化规则就行,它会根据Calendar存的时间值自动输出对应的AM/PM标记
修正后可直接用的代码
private fun timePicker() {
    val cal = Calendar.getInstance()
    val timelistener = TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
        // 删掉多余的手动减12的换算逻辑,直接用原始值赋值
        cal.set(Calendar.HOUR_OF_DAY, hourOfDay)
        cal.set(Calendar.MINUTE, minute)
        binding.addMoretimeStamp.text = SimpleDateFormat("h:mm a").format(cal.time)
    }
    TimePickerDialog(
        requireContext(),
        timelistener,
        cal.get(Calendar.HOUR_OF_DAY),
        cal.get(Calendar.MINUTE),
        false
    ).show()
}
补充提示

如果之后你一定要用12小时制的Calendar.HOUR字段(取值范围0-11),必须同步给Calendar.AM_PM字段设置对应的标记,不然还是会出现AM/PM识别错的问题,写法参考:

val hour12 = hourOfDay % 12
val period = if (hourOfDay < 12) Calendar.AM else Calendar.PM
cal.set(Calendar.HOUR, hour12)
cal.set(Calendar.AM_PM, period)

内容的提问来源于stack exchange,提问作者Muhammad Sajid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 10:54:04