Go语言实现12小时制HH:MM(am/pm)格式最小时间差计算
问题原因
使用time.Parse解析仅含12小时制时间的字符串时,Go会默认将所有解析结果的日期统一设置为0000-01-01,你给出的11:59pm会被解析为当日的23:59,12:00am会被解析为当日的00:00,直接做减法得到的是当日零点减去当日23:59的差值,自然和跨午夜的预期结果不符。
解决方案
我们可以基于24小时的时间环形特性,对原始差值做归一化处理,得到最小差值:
ref, _ := time.Parse("03:04pm", "11:59pm") t, _ := time.Parse("03:04pm", "12:00am") rawDiff := t.Sub(ref).Minutes() const dayMinutes = 24 * 60 // *一天总分钟数1440* const halfDayMinutes = 12 * 60 // *半天总分钟数720* // 将差值归一到 [0, 1440) 区间 modDiff := int(rawDiff) % dayMinutes if modDiff < 0 { modDiff += dayMinutes } // 取环形最小差值,超过半天则取反向差值 minDiff := modDiff if modDiff > halfDayMinutes { minDiff = dayMinutes - modDiff } fmt.Println(minDiff) // 输出 1,符合预期
逻辑说明
- 无日期的12小时制时间天然属于环形的24小时周期,直接按线性时间计算会出现跨时段偏差
- 取模加负数修正的操作,是把所有差值统一转换为「t相对于ref在未来24小时内的差值」
- 由于环形特性,超过12小时的差值,反方向的差值会更小,所以做最后一步调整
如果你的业务需要保留时间差的正负方向(比如判断t在ref之前还是之后),可以根据需求调整最后一步的判断逻辑,无需直接取绝对值最小的结果。
内容的提问来源于stack exchange,提问作者Rza
相关产品推荐
相关产品推荐

