Java 使用joda time获取自2000年以来的秒数

Java 使用joda time获取自2000年以来的秒数,java,date,datetime,Java,Date,Datetime,我将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 DateTi

我将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年以来的秒数,但它给了我一个负数。我可能做错了什么?

这是因为int溢出

移除铸件并将返回类型从
int
更改为
long

以毫秒为单位的当前时间为~
1404942594081

以毫秒为单位的开始时间是
946713600000

区别在于~

458229057398
将其强制转换为整数值将溢出到

-1332420848
因为
int
的最大值是
2147483647

只要把它放在
long

如果您想将其保持为
int
,则此代码将在2068年1月19日之前有效

return (int)(time.getMillis() - zeroPointTime.getMillis())/1000;
int
的强制转换应用于除以1000之前的减法

long
int
的转换在
int
范围内溢出,给出一个负值。在除法后施法

return (int) ((time.getMillis() - zeroPointTime.getMillis()) / 1000);

如果你真的需要
int
值。

2000年1月1日大约是946684800000毫秒,大约是458257821000毫秒前。此数字大于整数可以保持的毫秒数(2147483647)。这意味着您对
int
的强制转换将导致您看到的结果。

正如其他人所说,这是由于整数溢出造成的。只需添加括号即可:

return (int)((time.getMillis() - zeroPointTime.getMillis())/1000);
但是使用
持续时间将更干净:

Duration duration = new Duration(zeroPointTime, currentTime);
return (int) duration.getStandardSeconds();

只是一个无关紧要的评论:如果您的目标平台是Java8,为什么要使用joda时间罐?Java 8包含一个时间包(Java.time),它的api与joda time非常相似,不需要外部依赖关系。
持续时间+1,但将其保持在
int
将使其工作到2068年1月19日only@Jigar:是的,但我认为这是一项要求。我怀疑现在编写的大多数代码都将被以下代码替换:)