在java中计算日期/时间差异

Lon*_*don 143 java time

我想计算2小时/分钟/秒之间的差异.

我的代码在这里有点问题:

String dateStart = "11/03/14 09:29:58";
String dateStop = "11/03/14 09:33:43";

// Custom date format
SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");  

Date d1 = null;
Date d2 = null;
try {
    d1 = format.parse(dateStart);
    d2 = format.parse(dateStop);
} catch (ParseException e) {
    e.printStackTrace();
}    

// Get msec from each, and subtract.
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000;         
long diffMinutes = diff / (60 * 1000);         
long diffHours = diff / (60 * 60 * 1000);                      
System.out.println("Time in seconds: " + diffSeconds + " seconds.");         
System.out.println("Time in minutes: " + diffMinutes + " minutes.");         
System.out.println("Time in hours: " + diffHours + " hours."); 
Run Code Online (Sandbox Code Playgroud)

这应该产生:

Time in seconds: 45 seconds.
Time in minutes: 3 minutes.
Time in hours: 0 hours.
Run Code Online (Sandbox Code Playgroud)

但是我得到了这个结果:

Time in seconds: 225 seconds.
Time in minutes: 3 minutes.
Time in hours: 0 hours.
Run Code Online (Sandbox Code Playgroud)

谁能看到我在这里做错了什么?

Adm*_*mit 210

我更喜欢使用建议的java.util.concurrent.TimeUnit课程.

long diff = d2.getTime() - d1.getTime();//as given

long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
long minutes = TimeUnit.MILLISECONDS.toMinutes(diff); 
Run Code Online (Sandbox Code Playgroud)

  • @Mark我不同意.你错过了问题的重点.尽管他在帖子的其余部分使用了"以秒为单位的时间"这一短语,但他明确表示他实际上并不想要一个简单的转换,他想要剩下的.这比接受的答案效率低(使用方法调用,即使在JVM字节码中也是一些指令),不太清楚(它更长,坦率地说,如果某些东西在该上下文中发现"1000"或"60"是魔术数字,他们没有使用完整的套牌)而且,从枢轴上看,它没有做OP想要的. (13认同)

Pet*_*rey 93

尝试

long diffSeconds = diff / 1000 % 60;  
long diffMinutes = diff / (60 * 1000) % 60; 
long diffHours = diff / (60 * 60 * 1000);
Run Code Online (Sandbox Code Playgroud)

注意:这假设diff是非负的.


hel*_*ldt 41

如果您能够使用外部库,我建议您使用Joda-Time,注意:

Joda-Time是Java SE 8之前Java事实上的标准日期和时间库.现在要求用户迁移到java.time(JSR-310).

计算之间的示例:

Seconds.between(startDate, endDate);
Days.between(startDate, endDate);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您正在处理2个java.util.Date对象,那么您需要使用Days.daysBetween(LocalDate.fromDateFields(startDate),LocalDate.fromDateFields(endDate)); (8认同)
  • 目前的做法是什么?(使用JSR-310) (3认同)

Yve*_*tin 18

从Java 5开始,您可以使用java.util.concurrent.TimeUnit避免在代码中使用像Magic和1000这样的Magic Numbers.

顺便说一句,你应该注意你的计算中的闰秒:一年的最后一分钟可能有一个额外的闰秒,所以它确实持续61秒而不是预期的60秒.ISO规范甚至计划可能61秒.你可以在java.util.Datejavadoc 找到细节.

  • 除非有很好的商业理由来包含那些杂散的闰秒,否则你可以放心地将它们视为一种有趣但非物质的科学好奇心。 (2认同)
  • «它确实持续了 60 秒,而不是预期的 59 秒» 您的意思是它持续了 61 秒 (`0..60`),而不是预期的 60 秒 (`0..59`)。;) (2认同)

小智 13

试试这个友好的时差表示(以毫秒为单位):

String friendlyTimeDiff(long timeDifferenceMilliseconds) {
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = timeDifferenceMilliseconds / ((long)60 * 60 * 1000 * 24 * 365);

    if (diffSeconds < 1) {
        return "less than a second";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes";
    } else if (diffDays < 1) {
        return diffHours + " hours";
    } else if (diffWeeks < 1) {
        return diffDays + " days";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks";
    } else if (diffYears < 1) {
        return diffMonths + " months";
    } else {
        return diffYears + " years";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在线 long diffYears = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 365)); 你需要稍后转换 long ,否则除数是 int 并溢出:diffYears = (timeDifferenceMilliseconds / ((long)60 * 60 * 1000 * 24 * 365)); (2认同)
  • 我已经修复了代码 (2认同)

Dar*_*ind 7

我知道这是一个老问题,但我最终做了一些与接受的答案略有不同的事情。人们谈论这TimeUnit门课,但没有按照OP想要的方式使用它的答案。

所以这是另一个解决方案,如果有人错过它;-)

public class DateTesting {
    public static void main(String[] args) {
        String dateStart = "11/03/14 09:29:58";
        String dateStop = "11/03/14 09:33:43";

        // Custom date format
        SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");  

        Date d1 = null;
        Date d2 = null;
        try {
            d1 = format.parse(dateStart);
            d2 = format.parse(dateStop);
        } catch (ParseException e) {
            e.printStackTrace();
        }    

        // Get msec from each, and subtract.
        long diff = d2.getTime() - d1.getTime();

        long days = TimeUnit.MILLISECONDS.toDays(diff);
        long remainingHoursInMillis = diff - TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(remainingHoursInMillis);
        long remainingMinutesInMillis = remainingHoursInMillis - TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(remainingMinutesInMillis);
        long remainingSecondsInMillis = remainingMinutesInMillis - TimeUnit.MINUTES.toMillis(minutes);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(remainingSecondsInMillis);

        System.out.println("Days: " + days + ", hours: " + hours + ", minutes: " + minutes + ", seconds: " + seconds);
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然自己计算差异是可以的,但这样做没有多大意义,我认为这TimeUnit是一个被高度忽视的类。

  • 谢谢!我也是这么想的,不过你加快了速度:) (2认同)

Jos*_*ino 7

这是一个建议,使用TimeUnit, 获取每个时间部分并对其进行格式化。

private static String formatDuration(long duration) {
    long hours = TimeUnit.MILLISECONDS.toHours(duration);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) % 60;
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) % 60;
    long milliseconds = duration % 1000;
    return String.format("%02d:%02d:%02d,%03d", hours, minutes, seconds, milliseconds);
}

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss,SSS");
Date startTime = sdf.parse("01:00:22,427");
Date now = sdf.parse("02:06:38,355");
long duration = now.getTime() - startTime.getTime();
System.out.println(formatDuration(duration));
Run Code Online (Sandbox Code Playgroud)

结果是:01:06:15,928


Joe*_*ckx 6

这基本上是一个数学问题而不是java问题.

您收到的结果是正确的.这是因为225秒是3分钟(进行整体划分时).你想要的是这个:

  • 除以1000得到秒数 - >休息是毫秒
  • 将它除以60得到分钟数 - >休息是秒
  • 除以60得到小时数 - >休息是分钟

或者在java中:

int millis = diff % 1000;
diff/=1000;
int seconds = diff % 60;
diff/=60;
int minutes = diff % 60;
diff/=60;
hours = diff;
Run Code Online (Sandbox Code Playgroud)


bob*_*e01 5

Date使用您的时间差异作为构造函数创建一个对象,
然后使用 Calendar 方法获取值..

Date diff = new Date(d2.getTime() - d1.getTime());

Calendar calendar = Calendar.getInstance();
calendar.setTime(diff);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
Run Code Online (Sandbox Code Playgroud)

  • 这些方法已被弃用。 (4认同)
  • 工作正常,但你一定不要忘记设置时区:`Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));` (2认同)