Java中Time转换为long时值异常?如何将时间转为秒运算
为什么Java中
Time转long会得到负数?怎么正确转成秒做加减? 嘿,这个问题其实和时区直接相关,我来给你掰扯清楚~
先解释为什么会出现-3600000
你用的java.sql.Time本质上继承自java.util.Date,它的getTime()方法返回的是从1970-01-01 00:00:00 UTC(世界标准时间)到该时间点的毫秒数。
当你执行Time.valueOf("00:00:00")时,这个00:00:00是你本地时区的凌晨0点。假设你的本地时区是UTC+1(比如欧洲中部时间、西非时间等),那这个本地时间对应的UTC时间就是1969-12-31 23:00:00——比1970年的UTC零点早了1小时,所以毫秒数就是-3600*1000 = -3600000,刚好是-1小时的毫秒数。
如果你的时区是UTC+8(比如北京时间),那这个值会变成-28800000(-8小时),道理是一样的。
你的需求:转成秒做加减运算,怎么处理?
你要的是一天内的时分秒相对值(比如00:00:00对应0秒,01:00:00对应3600秒),但getTime()给的是带时区的绝对时间戳,完全不是一回事。这里分两种情况给你解决方案:
方案1:用Java 8+的LocalTime(强烈推荐)
Java 8引入的java.time.LocalTime是专门用来处理“一天中的时间”的类,它完全不涉及时区,完美匹配你的需求:
// 解析时分秒字符串 LocalTime localTime = LocalTime.parse("00:00:00"); // 转成当天的秒数(0到86399) long seconds = localTime.toSecondOfDay(); // 结果是0,完全符合预期 // 直接做加减运算 LocalTime oneHourLater = localTime.plusSeconds(3600); // 变成01:00:00 LocalTime thirtyMinutesEarlier = localTime.minusSeconds(1800); // 变成23:30:00
这个API设计得非常直观,而且没有时区坑,是处理时分秒加减的最优选择。
方案2:如果必须用旧的java.sql.Time
如果因为项目限制不能用Java 8+的API,那可以手动拆分时分秒计算,或者强制用UTC时区处理:
Time t = Time.valueOf("00:00:00"); // 方式1:直接拆分时分秒(注意getHours等方法已过时,但仍可使用) long seconds = t.getHours() * 3600 + t.getMinutes() * 60 + t.getSeconds(); // 结果0 // 方式2:用Calendar指定UTC时区计算 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.setTime(t); long secondsUtc = cal.get(Calendar.HOUR_OF_DAY)*3600 + cal.get(Calendar.MINUTE)*60 + cal.get(Calendar.SECOND); // 结果0
不过这种方式代码更繁琐,不如LocalTime简洁。
总结一下
- 出现负数的核心原因:
Time.getTime()返回的是带时区的绝对时间戳,你的本地0点对应UTC的前一天晚23点(或更早),所以得到负的毫秒数。 - 处理时分秒加减的正确姿势:用Java 8+的
LocalTime,它专注于一天内的时间,没有时区干扰,API友好。
内容的提问来源于stack exchange,提问作者Anthony J
相关产品推荐
相关产品推荐

