java.util.Date中的毫秒没有得到很好的解释

java.util.Date中的毫秒没有得到很好的解释,java,date,milliseconds,Java,Date,Milliseconds,我有两个java日期,格式为yyyy-MM-dd HH:MM:ss.SSS。我需要做一个简单的算术运算。我的代码是: SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String out = resu.getString(3); Date dateOut = formatter.parse(out); String in = resu.getString(4); Date dateIn

我有两个java日期,格式为yyyy-MM-dd HH:MM:ss.SSS。我需要做一个简单的算术运算。我的代码是:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
String out = resu.getString(3);
Date dateOut = formatter.parse(out);
String in = resu.getString(4);
Date dateIn = formatter.parse(in);
long msDiff = dateOut.getTime() - dateIn.getTime();
如果两个日期都有3毫秒,则此操作正常,例如:

dateIn = 2015-10-14 16:32:20.037
dateOut = 2015-10-14 16:32:20.093
但是当一个日期有一个或两个数字,而不是在右边用零来完成值时,它会在左边完成,这当然会改变操作的结果。例如

dateIn = 2015-10-14 16:32:20.05
dateOut = 2015-10-14 16:32:20.067

dateOut - dateIn = 062 //this is wrong, it should be 067 - 050 = 17.
我做错了什么

我没有找到一个好的解决方案,所以我做了一个很好的解决方案。它检查毫秒数并始终返回三位

public static String completeDate (String date) {
    String digits = date.substring(date.indexOf("."));
    int cantDigits = digits.length();
    while (cantDigits < 4){
        digits = digits + "0";
        cantDigits = digits.length();
    }
    String newDate = date.substring(0,date.indexOf(".")) + digits;
    return newDate;
}
公共静态字符串完成日期(字符串日期){
字符串数字=date.substring(date.indexOf(“.”);
int cantdights=位数.length();
而(数字<4){
位数=位数+0;
cantDigits=数字。长度();
}
字符串newDate=date.substring(0,date.indexOf(“.”)+数字;
返回newDate;
}

如果通过
SimpleDataFormat
将它们转换为
java.util.Date
java.sql.Date
,则
timestam1.getTime()-timestam2.getTime()
将产生正确的千秒数

这个测试确实表明断言失败了。您可以通过在末尾添加额外的零来修复它

@Test
public void validateDateComparison() {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    try {
        Date dateStart = dateFormat.parse("2015-10-14 16:32:20.05");
        Date dateEnd = dateFormat.parse("2015-10-14 16:32:20.067");

        assertEquals(17, dateEnd.getTime() - dateStart.getTime());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
样本:


不确定这是否正确。

由于小数点后的位数不同,这两个日期在技术上有不同的模式。从:

图案字母通常是重复的,因为它们的数量决定了确切的表示方式:

对于格式化,图案字母的数量是最小位数,较短的数字将被零填充到此数量。对于解析,除非需要分隔两个相邻字段,否则将忽略模式字母的数量


鉴于此,日期
2015-10-14 16:32:20.05
被解释为
2015-10-14 16:32:20.005
(分数用零填充三位数),因此相差62毫秒。您应该为这两个日期使用不同的格式设置程序,或者很可能应该查看这两个值是如何插入的,以及它们具有不同格式的原因。

您是如何读取日期的?确实-请展示一个简短但完整的程序来演示此问题。请注意,如果您有一个以“.05”结尾的值,那么您就没有以“ss.SSS”结尾的格式的日期。值在数据库中,我从结果集中获取值,然后用SimpleDataFormat解析它。请编辑您的代码并添加额外的信息。抱歉,我编辑了代码。OP非常清楚,
dateOut.getTime()-dateIn.getTime()
没有给出预期的答案。对我来说,看最后一个代码片段,问题中的这一点并不明显。我正在做的是,它没有达到预期效果。OK,我看到,在数据库中,值是正确的,05与050相同,因此不必添加最后的零。我可以使用不同的模式,因为我不知道该值有多少位数,可以是1、2或3。谢谢你的回答。你所解释的可能是正确的,但它不能解释为什么它会转换为0.05005@user3285427我在文档中提到了为什么“对于格式化,模式字母的数量是最小位数,较短的数字是零填充到这个数量”。
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);

// duration in ms between two instants
Duration dur = new Duration(start, end);

// calc will be the same as end
DateTime calc = start.plus(dur);