使用Date()计算时间戳差值结果错误,求助排查方案
时间戳差值计算结果不符合预期的排查思路
问题场景
计算两个时间戳的差值时,使用Date()处理后结果不符合预期:
- 日志输出的时间对:
test delta, departed = Fri Feb 21 14:00:01 GMT+01:00 2025, plan = Fri Feb 21 10:01:48 GMT+01:00 2025
- 预期结果:
+3:58 - 实际结果:
+4:58
相关代码
Timber.d("test delta, departed = $time1, plan = $time2") val deltaMills = time1.time - time2.time val sign = if (deltaMills < 0) "-" else if (deltaMills > 0) "+" else "" val pattern = if (Calendar.getInstance().fromDate(it).get(Calendar.HOUR_OF_DAY) == 0) "m" else "H:mm" val result = "$sign${SimpleDateFormat(pattern, Locale.getDefault()).format(Date(deltaMills.absoluteValue))}"
问题原因与解决思路
核心误区:用Date类处理时间间隔
Date(deltaMills.absoluteValue)的本质是把毫秒数解析成从1970-01-01 00:00:00 UTC开始的时间点,而非纯粹的时间间隔。如果你的时区是GMT+01:00,UTC的1970-01-01 00:00:00对应本地时间1970-01-01 01:00:00。
以你的场景为例,时间差绝对值是3小时58分23秒(约14293000毫秒),对应UTC时间1970-01-01 03:58:23,转换为GMT+01:00本地时间就是1970-01-01 04:58:23,所以SimpleDateFormat格式化后得到4:58,这就是误差来源。
正确处理方式:直接计算时分
不要借助Date和SimpleDateFormat处理时间间隔,直接通过毫秒差计算小时和分钟:
val deltaMills = time1.time - time2.time val sign = if (deltaMills < 0) "-" else if (deltaMills > 0) "+" else "" val totalMinutes = deltaMills.absoluteValue / (1000 * 60) val hours = totalMinutes / 60 val minutes = totalMinutes % 60 // 若需要分钟补0,用String.format("%02d", minutes) val result = "$sign$hours:$minutes"
额外注意
代码中Calendar.getInstance().fromDate(it)的it变量上下文不明确,需确认其取值是否正确,避免影响pattern的选择逻辑。
内容的提问来源于stack exchange,提问作者Konstantin Konopko




