SimpleDateFormat比较问题

时间:2013-07-15 16:31:15

标签: java simpledateformat

我想以字符串格式比较两个日期,并以HH:MM:SS:SSS作为字符串返回结果。 当我尝试使用startDate为15 Jul 2013 17:08:34.903和endDate时运行以下内容 15 Jul 2013 17:08:51.247我希望看到00:00:16.344的结果。相反,我得到01:00:16.344的差异。任何想法为什么会发生这种情况??

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("d MMM yyyy HH:mm:ss.SSS");
    private static final SimpleDateFormat DATE_FORMAT_HH_MM_SS = new SimpleDateFormat("HH:mm:ss.SSS");

    public String calculateDuration(String startDateStr, String endDateStr){

        String methodName = "calculateDuration";
        try {           
            Date startDate = DATE_FORMAT.parse(startDateStr);
            Date endDate = DATE_FORMAT.parse(endDateStr);          
            long diff = endDate.getTime() - startDate.getTime();        
            return DATE_FORMAT_HH_MM_SS.format(diff);  

3 个答案:

答案 0 :(得分:0)

JDK Date API非常糟糕。我建议使用Joda Time库,但如果必须使用JDK Date API,请尝试以下代码:

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
        "d MMM yyyy HH:mm:ss.SSS");

public String calculateDuration(String startDateStr, String endDateStr)
        throws ParseException {

    String methodName = "calculateDuration";
    Date startDate = DATE_FORMAT.parse(startDateStr);
    Date endDate = DATE_FORMAT.parse(endDateStr);

    // in milliseconds
    long diff = endDate.getTime() - startDate.getTime();

    long diffMiliseconds = diff % 1000;
    long diffSeconds = diff / 1000 % 60;
    long diffMinutes = diff / (60 * 1000) % 60;
    long diffHours = diff / (60 * 60 * 1000) % 24;

    return String.format("%02d:%02d:%02d.%02d", diffHours, diffMinutes,
            diffSeconds, diffMiliseconds);
}

答案 1 :(得分:0)

您尚未使用Calendar对象初始化SimpleDateFormat格式化程序,因此它使用默认格式来执行映射。我猜这个默认日历正在识别DST。当你.parse()日期时,这并不明显,因为DST调整在减法中取消。

将结果转换为HMS格式时,格式化程序再次应用DST调整。由于此步骤中没有减法,因此它会显示在您的结果中。

在我看来,每当有人有日期算术问题时,橡皮图章,膝跳反射反应就是“使用JodaTime”。我们都喜欢JodaTime;它是一个精心设计的API。但使用它仍然是一个外部依赖,除非你需要它,你不应该使用它。在我看来,对于这种情况你根本不需要JodaTime ...你只需要Java Calendar API来解析你的日期时间到日期。这就是你所需要的一切。

一旦你有毫秒的差异,你真的应该避免使用格式化程序来转换结果。使用简单的算术将更加高效:

private static final SimpleDateFormat DATE_FORMAT = 
    new SimpleDateFormat("d MMM yyyy HH:mm:ss.SSS");

private static final int DAYS    = 0;
private static final int HOURS   = 1;
private static final int MINUTES = 2;
private static final int SECONDS = 3;
private static final int MILLIS  = 4;
private final int[] result = new int[MILLIS];

public String calculateDuration(String startDateStr, String endDateStr){

    try {           
        Date startDate = DATE_FORMAT.parse(startDateStr);
        Date endDate = DATE_FORMAT.parse(endDateStr);
    } catch (Exception e) { /* exception processing */ }

    long diff = endDate.getTime() - startDate.getTime();        

    double d; 
    for (int i = DAYS; i <= MILLIS; i++) {    
        switch(i) {
            case DAYS:
                d = ((double) diff) / (86400.0 * 1000.0);
                break;
            case HOURS:
                d = d * 24.0;   break;
            case MINUTES:  case SECONDS:
                d = d * 60.0;   break;
            case MILLIS:
                d = d * 1000.0; break;
        }
        result[i] = (int) Math.floor(d);
        d = d - (double) result[i];
    }

在最后一个for循环结束时,数组result包含与您的日期减法派生的DAYS,HOURS,MINUTES,SECONDS和MILLIS数相对应的整数。无需创建,分配或调用任何对象即可获得此结果。您现在可以轻松使用String.format()函数将这些整数放入您选择的字符串格式中。

答案 2 :(得分:0)

因为在评论中你说你只是在测量应用程序的运行时间,所以根本不要涉及Date,SimpleDateFormat或Calendar。

long tic = System.nanoTime();

......就是你所需要的。当你手上有苍蝇拍时,不要用大炮杀死蚊子。