如何在Java中找到两个日期之间的持续时间?

120

我有两个DateTime对象,需要找出它们之间的时间差

我有以下代码,但不确定如何继续才能得到以下期望结果:

示例

      11/03/14 09:30:58
      11/03/14 09:33:43
      elapsed time is 02 minutes and 45 seconds
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/15 09:30:58
      elapsed time is a day
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/16 09:30:58
      elapsed time is two days
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/16 09:35:58
      elapsed time is two days and 05 minutes
      

代码:

    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 % 60;
    long diffMinutes = diff / (60 * 1000) % 60;
    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.");

5
请查看 Joda Time,它内置了对此的支持。 - Erik Pragt
1
你的代码有什么问题,只需要进行一些微调就可以达到所需的输出结果,让我们试试看。 - Abubakkar
你需要澄清你的问题是什么。有些人可能会认为你在计算方面有困难,但在我看来,你似乎在编写输出逻辑方面有困难。 - Peter Lawrey
1
@PeterLawrey 我已经提供了不同的例子。 - J888
1
@aquestion的重复意味着两个问题期望相同的结果,而这个问题的期望输出与您提供的不同。 - Tim Norman
显示剩余7条评论
19个回答

227

使用Java内置类TimeUnit可以更好地处理日期差异的转换。它提供了实用方法来完成这个任务:

Date startDate = // Set start date
Date endDate   = // Set end date

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

long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);

2
转换为汉语: 另外,long diffInSeconds = TimeUnit.SECONDS.convert(duration,TimeUnit.MILLSECONDS); - gerardw
3
这是最佳答案。 - Angel Cuenca
2
我表示赞同;这个答案是最好的。 - Mushy
3
不依赖第三方库。 - crmepham
1
OP 需要天数、小时和分钟的差异。其中,小时和分钟不是绝对值,而是余数。这个解决方案简洁但不能提供相同的答案。 - Lluis Martinez
显示剩余3条评论

73

请尝试以下操作

{
        Date dt2 = new DateAndTime().getCurrentDateTime();

        long diff = dt2.getTime() - dt1.getTime();
        long diffSeconds = diff / 1000 % 60;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000);
        int diffInDays = (int) ((dt2.getTime() - dt1.getTime()) / (1000 * 60 * 60 * 24));

        if (diffInDays > 1) {
            System.err.println("Difference in number of days (2) : " + diffInDays);
            return false;
        } else if (diffHours > 24) {

            System.err.println(">24");
            return false;
        } else if ((diffHours == 24) && (diffMinutes >= 1)) {
            System.err.println("minutes");
            return false;
        }
        return true;
}

21
此答案忽略了定义一天开始和结束的时区。此答案忽略了夏令时和其他异常情况,这意味着一天的长度并不总是24小时。请查看使用Joda-Time或java.time库的正确答案。 - Basil Bourque
3
正如Basil所指出的,这个答案是错误的。如果结束日期在夏令时期间,但开始日期不在此时,则会得到错误的天数。 - Dawood ibn Kareem

50

使用Joda-Time库。

DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
long hours = p.getHours();
long minutes = p.getMinutes();

Joda Time有一个时间间隔的概念:

Interval interval = new Interval(oldTime, new Instant());

另一个例子 日期差异

另一个 链接

或者使用Java-8(其中集成了Joda-Time概念)

Instant start, end;//
Duration dur = Duration.between(start, stop);
long hours = dur.toHours();
long minutes = dur.toMinutes();

2
这应该是被接受的答案。Joda时间是正确的选择。 - Bizmarck
处理时区、夏令时变化等问题的唯一安全方法是正确处理。 - Newtopian
1
只是一个小笔误:你的第二行应该是“end”而不是“stop”(“Duration dur = Duration.between(start, stop);”)。 - Mohamad Fakih

13

以下是如何在Java 8中解决问题的方法,就像shamimz的答案一样。

来源: http://docs.oracle.com/javase/tutorial/datetime/iso/period.html

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);

Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);

System.out.println("You are " + p.getYears() + " years, " + p.getMonths() + " months, and " + p.getDays() + " days old. (" + p2 + " days total)");

代码生成类似于以下内容的输出:

You are 53 years, 4 months, and 29 days old. (19508 days total)
我们必须使用 LocalDateTime http://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html 来获取小时、分钟和秒的差异。

这个方法非常像MayurB回答的Joda-Time方式。http://joda-time.sourceforge.net/ - johnkarka
1
你的 Joda-Time 链接已经过时了。当前的URL是http://www.joda.org/joda-time/。 - Basil Bourque
LocalDate不存储时间和时区,它仅保留日期-月份-年份。请参见https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html - Shamim Ahmmed
这并没有考虑时间因素。OP的问题涉及到秒、分钟和小时。 - mkobit

8
您可以创建像这样的方法:
public long getDaysBetweenDates(Date d1, Date d2){
return TimeUnit.MILLISECONDS.toDays(d1.getTime() - d2.getTime());
}

该方法将返回两个日期之间的天数。

简短回答。解决方案必须像这样。 - REMITH

7
Date d2 = new Date();
Date d1 = new Date(1384831803875l);

long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000);
int diffInDays = (int) diff / (1000 * 60 * 60 * 24);

System.out.println(diffInDays+"  days");
System.out.println(diffHours+"  Hour");
System.out.println(diffMinutes+"  min");
System.out.println(diffSeconds+"  sec");

首先非常感谢您简短而友好的回答。我在您的解决方案中遇到了一个问题,我有两个日期:06_12_2017_07_18_02_PM和另一个是06_12_2017_07_13_16_PM,但我得到的是286秒,而不是应该得到的46秒。 - Siddhpura Amit

6

正如Michael Borgwardt在他的回答中所写的

int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Note that this works with UTC dates, so the difference may be a day off if you look at local dates. And getting it to work correctly with local dates requires a completely different approach due to daylight savings time.


1
手动乘以这些值不是一个好主意。最好使用Java的TimeUnit类来完成。 - Shamim Ahmmed
2
你所说关于本地日期的内容是不正确的。根据API文档,getTime()方法返回此 Date 对象表示的自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。如果两个数字具有相同的单位,则可以安全地将它们相加和相减。 - Ingo
1
是的,它是安全的,但代码不够干净,因为Java提供了标准的处理方式。 - Shamim Ahmmed
1
除了提供答案的链接外,您还必须清楚地引用您从其他人那里复制的措辞。 - Brad Larson

5
在Java 8中,您可以使用DateTimeFormatter, DurationLocalDateTime。以下是一个示例:
final String dateStart = "11/03/14 09:29:58";
final String dateStop = "11/03/14 09:33:43";

final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(ChronoField.MONTH_OF_YEAR, 2)
        .appendLiteral('/')
        .appendValue(ChronoField.DAY_OF_MONTH, 2)
        .appendLiteral('/')
        .appendValueReduced(ChronoField.YEAR, 2, 2, 2000)
        .appendLiteral(' ')
        .appendValue(ChronoField.HOUR_OF_DAY, 2)
        .appendLiteral(':')
        .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
        .appendLiteral(':')
        .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
        .toFormatter();

final LocalDateTime start = LocalDateTime.parse(dateStart, formatter);
final LocalDateTime stop = LocalDateTime.parse(dateStop, formatter);

final Duration between = Duration.between(start, stop);

System.out.println(start);
System.out.println(stop);
System.out.println(formatter.format(start));
System.out.println(formatter.format(stop));
System.out.println(between);
System.out.println(between.get(ChronoUnit.SECONDS));

5
我亲自尝试过这个方法,你可以尝试一下,希望有所帮助。如果有任何疑问,请告诉我。
Date startDate = java.util.Calendar.getInstance().getTime(); //set your start time
Date endDate = java.util.Calendar.getInstance().getTime(); // set  your end time

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


long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);

Toast.makeText(MainActivity.this, "Diff"
        + duration + diffInDays + diffInHours + diffInMinutes + diffInSeconds, Toast.LENGTH_SHORT).show(); **// Toast message for android .**

System.out.println("Diff" + duration + diffInDays + diffInHours + diffInMinutes + diffInSeconds); **// Print console message for Java .**

1
长时间(毫秒)转化为秒数:long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration); - Keshav Gera

2

这是代码:

        String date1 = "07/15/2013";
        String time1 = "11:00:01";
        String date2 = "07/16/2013";
        String time2 = "22:15:10";
        String format = "MM/dd/yyyy HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date fromDate = sdf.parse(date1 + " " + time1);
        Date toDate = sdf.parse(date2 + " " + time2);

        long diff = toDate.getTime() - fromDate.getTime();
        String dateFormat="duration: ";
        int diffDays = (int) (diff / (24 * 60 * 60 * 1000));
        if(diffDays>0){
            dateFormat+=diffDays+" day ";
        }
        diff -= diffDays * (24 * 60 * 60 * 1000);

        int diffhours = (int) (diff / (60 * 60 * 1000));
        if(diffhours>0){
            dateFormat+=diffhours+" hour ";
        }
        diff -= diffhours * (60 * 60 * 1000);

        int diffmin = (int) (diff / (60 * 1000));
        if(diffmin>0){
            dateFormat+=diffmin+" min ";
        }
        diff -= diffmin * (60 * 1000);

        int diffsec = (int) (diff / (1000));
        if(diffsec>0){
            dateFormat+=diffsec+" sec";
        }
        System.out.println(dateFormat);

结果如下:

duration: 1 day 11 hour 15 min 9 sec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接