Java 两个 long 时间戳相差几分钟?先说清单位、取整和溢出

举报
yd_241387476 发表于 2026/11/09 09:28:17 2026/11/09
【摘要】 从两个 long 时间戳相差几分钟出发,说明单位、完整分钟、反向输入与溢出边界,并用 10 组 Java 实验验证 Duration 写法。

同样是“相差一分钟”,59 秒、60 秒和 61 秒在不同业务里可能得到不同答案。把两个 long 相减再除以 60000,隐含了三个约定:输入采用毫秒,结果只保留完整分钟,并且相减没有超出 long 的范围。本文从本站《比较两个long类型相差分钟数》的短问答出发,把这些约定展开,并补上一组可以直接运行的边界验证。

先确定需要哪一种分钟数

如果页面只展示已经经过多少个完整分钟,59 秒对应 0,60 秒对应 1,119 秒仍对应 1。如果要展示小数分钟,90 秒可以显示为 1.5。如果业务规定不足一分钟按一分钟算,哪怕只经过 1 毫秒也需要返回 1。这三种结果都可以合理,必须先由业务确定口径,再决定计算方法。

原问答中的两个值为 1595823600000L 和 1595827200000L。它们按 Unix 毫秒时间戳解释时,相差 3600000 毫秒,结果为 60 个完整分钟。这里的 long 只是存储类型,类型本身不能说明单位。接口字段建议使用 startMillis、endMillis 这样的名称,并在契约中明确是 Unix 毫秒时间戳。秒值误当成毫秒通常不会触发类型错误,却会让结果缩小一千倍。

用 Instant 与 Duration 表达经过的时间

下面的方法返回两个毫秒时间戳之间相差的完整分钟数,结果始终非负,适用于 Java 8 及以上版本。

import java.time.Duration;
import java.time.Instant;

public static long wholeMinutes(long startMillis, long endMillis) {
    return Duration.between(Instant.ofEpochMilli(startMillis),
            Instant.ofEpochMilli(endMillis)).abs().toMinutes();
}

先把毫秒时间戳转换成 Instant,再求两者之间的 Duration,随后取绝对时长,最后转换为完整分钟。abs 放在 toMinutes 之前,能让后续取整始终面对非负时长。两个时间戳顺序交换时,方法返回相同结果。如果业务需要区分提前和逾期,应另外设计有方向的结果,保留原始时间先后关系。

这一计算衡量的是两个时间点间经过的时长。直接使用时间戳时,不需要为了换算分钟再加减时区偏移。如果输入最初来自“2026-11-09 09:00”这样的本地日期文本,则必须在转换为 Instant 的入口明确时区。日期文本的解释和时间戳之间的减法是两个不同步骤,接口边界要把它们交代清楚。

原始减法有哪些边界

在常见日期范围内,Math.abs((endMillis - startMillis) / 60000L) 可以算出完整分钟数。但如果方法承诺接受任意 long,直接减法可能先溢出。后面的除法和 Math.abs 无法恢复已经丢失的结果。

我用 Long.MIN_VALUE 和 Long.MAX_VALUE 验证这一点。原公式返回 0,使用上面的方法则返回 307445734561825。测试的期望值另用 BigInteger 做减法、取绝对值并整除 60000 得到,避免让被测代码和期望值重复同一条有溢出风险的算式。这是数值边界实验,实际业务通常还应限制可以接受的日期范围,例如拒绝明显超出系统运行周期的输入。

把口径写进测试

本次以 Java 8 目标编译运行了 10 组测试,包括相同时间、59999 毫秒、60000 毫秒、119999 毫秒、反向输入、负时间戳、跨过纪元零点、原文的一小时例子,以及 long 两端的正反两个方向,均通过。

对常见输入,可以先手工列出这几项期望。0 到 59999 返回 0,0 到 60000 返回 1,0 到 119999 返回 1,60000 到 0 仍返回 1。负时间戳可以表示纪元之前的时间,是否允许进入业务系统应由输入校验决定。

若业务要求向上取整,可以在非负 Duration 上先取完整分钟,再检查时长是否恰好等于 Duration.ofMinutes(wholeMinutes)。只要仍有余量,就加一。这样能直接表达“不足一分钟也计入”的业务意思。本文测试覆盖的是完整分钟方法,向上取整逻辑接入业务时,应另外验证零时长、恰好一分钟和多出一毫秒的情况。

本文根据本人网站“安全问答”的《比较两个long类型相差分钟数》(条目 ixaU)经 AI 辅助改写。API 行为参照 Oracle Java 8 API 的 java.time.Duration 文档,示例及数值边界已在本地验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。