我正在使用JodaTime jar和Oracle Java 8.我正在接收来自固件设备的数据包,它的开始时间是2000年1月1日的开始。我需要获得自2000年1月1日以来的秒数。数学似乎很简单,但由于某种原因它给了我一个负值,这个值出现在1999年的一个时间,而不是当前时间:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
public class TimeIssue {
private DateTime currentTime = DateTime.now(DateTimeZone.UTC);
private DateTime zeroPointTime = new DateTime(2000, 1, 1, 0, 0, DateTimeZone.UTC);
private void checkTime(){
System.out.println("current time: " + currentTime);
System.out.println("current time to secs: " + timetos(currentTime));
}
private int timetos(DateTime time){
return (int)(time.getMillis() - zeroPointTime.getMillis())/1000;
}
public static void main(String[] args) {
TimeIssue issue = new TimeIssue();
issue.checkTime();
}
}
输出:
current time: 2014-07-09T21:28:46.435Z
current time in seconds: -1304974
current time from seconds: 1999-12-16T21:30:26.000Z
我会假设从2000年时间减去当前时间(以毫秒为单位),以毫秒为单位除以1000将得出自2000年以来的当前时间(以秒为单位),但它给出了一个负数。我可能做错了什么?
答案 0 :(得分:7)
正如其他人所说,这是由于整数溢出。你可以只添加括号:
return (int)((time.getMillis() - zeroPointTime.getMillis())/1000);
但使用Duration
:
Duration duration = new Duration(zeroPointTime, currentTime);
return (int) duration.getStandardSeconds();
答案 1 :(得分:2)
在
return (int)(time.getMillis() - zeroPointTime.getMillis())/1000;
将int
的施法元素应用于之前的除以之前的。
从long
到int
的转换在int
范围内溢出,给出负值。分裂后应用演员
return (int) ((time.getMillis() - zeroPointTime.getMillis()) / 1000);
如果,您确实需要int
个值。
答案 2 :(得分:1)
这是因为int overflow
删除广告并将返回类型从int
更改为long
以毫秒为单位的当前时间为〜1404942594081
以毫秒为单位的开始时间为946713600000
差异是〜
458229057398
将其转换为整数值会溢出到
-1332420848
因为int
的最大值为2147483647
将其保存在long
如果您想将其保留到int
,则此代码最多可用Jan 19 2068
答案 3 :(得分:1)
2000年1月1日大约是946,684,800,000毫秒,大约是458,257,821,000毫秒。此数字大于int可容纳的毫秒数(2,147,483,647)。这意味着您投向int
会导致integer overflow,这就是您所看到的。