Java 简化格式比较问题

Java 简化格式比较问题,java,simpledateformat,Java,Simpledateformat,我想以字符串格式比较两个日期,并以HH:MM:SS:SSS作为字符串返回结果。 当我尝试运行以下代码时,起始日期为2013年7月15日17:08:34.903,结束日期为 2013年7月15日17:08:51.247我希望看到00:00:16.344的结果。相反,我得到的差值是01:00:16.344。你知道为什么会这样吗 private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("d MMM yyyy HH

我想以字符串格式比较两个日期,并以HH:MM:SS:SSS作为字符串返回结果。 当我尝试运行以下代码时,起始日期为2013年7月15日17:08:34.903,结束日期为
2013年7月15日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);  

JDK日期API非常糟糕。我建议使用库,但如果必须使用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);
}

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

将结果转换为HMS格式时,格式化程序将再次应用DST调整。因为这一步没有减法,所以它会出现在结果中

在我看来,每当有人问日期算术问题时,橡皮图章式的下意识反射反应就是“使用JodaTime”;这是一个精心编制的API。但是使用它仍然是一种外部依赖,除非你需要它,否则你不应该使用它。在我看来,在这种情况下,你根本不需要JodaTime。。。您只需要Java日历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];
    }
private静态最终简化格式日期\格式=
新的简化格式(“d MMM yyyy HH:mm:ss.SSS”);
私有静态最终整数天=0;
专用静态最终整数小时=1;
专用静态最终整数分钟=2;
专用静态最终整数秒=3;
专用静态最终整数毫秒=4;
私有最终整数[]结果=新整数[MILLIS];
公共字符串计算(字符串startDateStr、字符串endDateStr){
试试{
Date startDate=Date_FORMAT.parse(startDateStr);
Date endDate=Date\u FORMAT.parse(endDateStr);
}捕获(异常e){/*异常处理*/}
long diff=endDate.getTime()-startDate.getTime();
双d;

对于(int i=DAYS;i,因为在评论中您说您只是在测量应用程序的运行时间,所以根本不涉及日期、SimpleDataFormat或日历

long tic = System.nanoTime();

当你有一个苍蝇拍时,不要用大炮杀死蚊子。< / P>这是java吗?考虑给它语言TAGI认为你应该用来计算时间差(持续时间)。。这将简化您的生活。顺便说一句,如果从不同的线程调用
calculateDuration
,您的方法并不总是有效,因为
SimpleDataFormat
不是线程安全的。是的,它是Java,很抱歉,我应该在我的原始帖子中指定它。我的TZ是GMT。感谢您的建议,我将查看JodaTime。您正在尝试解释两个时间戳之间的差异(自Unix时代以来以毫秒为单位)作为一个新的时间戳。这是行不通的。Java标准API中没有对时间段提供合理支持的类。我不同意JodaTime的说法。虽然我同意人们不必总是使用它,但我仍然喜欢为此类问题指出它,因为它使处理日历数据变得更加容易,而且有些人已经这样做了还没听说过。当我第一次问起日历和日期时,我很高兴有人指给Joda看。@JannisAlexakis:Date对象之间的减法通常不需要日历API。在这种情况下,使用日历API不仅要慢得多,而且会导致错误,因为生成的间隔是映射的(有点错误)到日历日期。外部依赖性就是它们。如果人们普遍认为最好在可能的情况下取消它们,那么我认为我们可以同意在这种情况下取消一个。