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

时间:2015-10-14 20:30:24

标签: 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 = 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;
}

2 个答案:

答案 0 :(得分:4)

由于小数点后的位数不同,这两个日期在技术上有不同的模式。来自documentation of SimpleDateFormat

  

模式字母通常会重复,因为它们的数字决定了确切的呈现方式:

     

...

     

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

鉴于此,日期var PersonCollection = Backbone.Collection.extend({ model: PersonModel, url: function() { // Dummy JSFiddle endpoint // Example non-RESTful url "/api/entity/735/request/personDelete" return '/echo/json/'; }, /** * Override toJSON to loop through collection models making * custom objects containing specific attributes to be posted. */ toJSON: function() { console.log(this.models); var plucked = this.models.map(function(model) { return _.pick( model.toJSON(), ["id","name", "teams"] ) }); console.log(plucked); return plucked; }, save: function(options) { Backbone.sync('create', this, { success: function(data, textStatus, jqXHR) { console.log('Saved!', data); } }); } }); 被解释为2015-10-14 16:32:20.05(分数用零填充以具有三位数),因此差异为62毫秒。您应该为这两个日期使用不同的格式化程序,或者最有可能应查看这两个值的插入方式以及它们具有不同格式的原因。

答案 1 :(得分:0)

如果它们转换为java.util.Datejava.sql.DateSimpleDateFormat,则timestamp1.getTime() - timestamp2.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();
    }
}

JodaTime duration的示例:

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);

不确定JodaTime处理此duration是否正确。