计算Java 8中两个日期之间的天数


249

我知道有很多关于如何获取的问题,但是我想和使用新的Java 8 Date api进行示例。我也知道JodaTime库,但是我想要一种没有外部库的工作方式。

功能需要抱怨以下限制:

  1. 防止日期保存错误
  2. 输入是两个Date对象(没有时间,我知道localdatetime,但是我需要处理日期实例)

2
例如这样的事情?
MadProgrammer

@MadProgrammer不是真的-持续时间不是最适合的方式...
assylias 2014年

@assylias好吧,这比OP的要好
MadProgrammer 2014年

@assylias那是什么?
MadProgrammer 2014年

15
@MadProgrammer DAYS.between(localDate1, localDate2)
assylias 2014年

Answers:


432

如果需要逻辑日历日,请使用以下DAYS.between()方法java.time.temporal.ChronoUnit

LocalDate dateBefore;
LocalDate dateAfter;
long daysBetween = DAYS.between(dateBefore, dateAfter);

如果您想使用字面量的24小时制持续时间),则可以改用Duration此类:

LocalDate today = LocalDate.now()
LocalDate yesterday = today.minusDays(1);
// Duration oneDay = Duration.between(today, yesterday); // throws an exception
Duration.between(today.atStartOfDay(), yesterday.atStartOfDay()).toDays() // another option

有关更多信息,请参阅本文档


15
抛出一个异常,因为Duration.between方法需要能够支持SECONDS单元的时间对象。相反,请尝试Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays()
VGR 2014年

5
代替today.atTime(0, 0)你可以做today.atStartOfDay()
eee 2014年

5
@REACHUS -1可能有点苛刻,因为您建议的代码可以工作,但是Duration是用来测量“基于时间的时间”的。有一种内置的方法可以测量天数,而无需将日期转换为日期时间。
assylias,2014年

对于LocalDate,更好的答案是@Sunil B,其答案如下:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro

@Lappro为什么会更好?它使用与我的答案相同的方法
宪法

129

根据VGR的评论,这里可以使用:

ChronoUnit.DAYS.between(firstDate, secondDate)

38

您可以使用until()

LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
LocalDate christmas = LocalDate.of(2014, Month.DECEMBER, 25);

System.out.println("Until christmas: " + independenceDay.until(christmas));
System.out.println("Until christmas (with crono): " + independenceDay.until(christmas, ChronoUnit.DAYS));

4
我在第一个版本中遇到的问题until是它返回了Period对象。这将返回两个日期之间的年/月/日数,而不是实际的天数。而且Period上的getDays()仅返回天数部分(不考虑年数或月数),而不是总天数。第二个版本完全可以根据需要工作,以在两个日期之间获得几天的时间。
M. Justin

为此有一个完整的选择吗?因为它需要Android SDK中26以上
ralphgabb

11

您可以使用DAYS.betweenjava.time.temporal.ChronoUnit

例如

import java.time.temporal.ChronoUnit;

public long getDaysCountBetweenDates(LocalDate dateBefore, LocalDate dateAfter) {
    return DAYS.between(dateBefore, dateAfter);
}

9

如果startDateendDatejava.util.Date的实例

我们可以使用ChronoUnit 枚举中的between()方法:

public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
    //..
}

ChronoUnit.DAYS计算完成24小时的

import java.time.temporal.ChronoUnit;

ChronoUnit.DAYS.between(startDate.toInstant(), endDate.toInstant());

//OR 

ChronoUnit.DAYS.between(Instant.ofEpochMilli(startDate.getTime()), Instant.ofEpochMilli(endDate.getTime()));

7

在枚举java.time.temporal.ChronoUnit中使用DAYS 。下面是示例代码:

输出: *开始日期:2015-03-01和结束日期:2016-03-03之间的天数==>368。**开始日期:2016-03-03和结束日期之间的天数: 2015-03-01是==> -368 *

package com.bitiknow.date;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

/**
 * 
 * @author pradeep
 *
 */
public class LocalDateTimeTry {
    public static void main(String[] args) {

        // Date in String format.
        String dateString = "2015-03-01";

        // Converting date to Java8 Local date
        LocalDate startDate = LocalDate.parse(dateString);
        LocalDate endtDate = LocalDate.now();
        // Range = End date - Start date
        Long range = ChronoUnit.DAYS.between(startDate, endtDate);
        System.out.println("Number of days between the start date : " + dateString + " and end date : " + endtDate
                + " is  ==> " + range);

        range = ChronoUnit.DAYS.between(endtDate, startDate);
        System.out.println("Number of days between the start date : " + endtDate + " and end date : " + dateString
                + " is  ==> " + range);

    }

}

7

每个人都在说使用ChronoUnit.DAYS.between,但这只是委托给您可以调用的另一种方法。所以你也可以做firstDate.until(secondDate, ChronoUnit.DAYS)

两者的文档实际上都提到了这两种方法,并说使用可读性更高的方法。


FWIW ...我不确定为什么两者都存在。有没有一个时代更具可读性而另一个时代更具可读性?什么时候/为什么?
nafg

4

干得好:

public class DemoDate {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);

        //add 1 month to the current date
        LocalDate date2 = today.plus(1, ChronoUnit.MONTHS);
        System.out.println("Next month: " + date2);

        // Put latest date 1st and old date 2nd in 'between' method to get -ve date difference
        long daysNegative = ChronoUnit.DAYS.between(date2, today);
        System.out.println("Days : "+daysNegative);

        // Put old date 1st and new date 2nd in 'between' method to get +ve date difference
        long datePositive = ChronoUnit.DAYS.between(today, date2);
        System.out.println("Days : "+datePositive);
    }
}

4

获取圣诞节前一天的天数,试试看

System.out.println(ChronoUnit.DAYS.between(LocalDate.now(),LocalDate.of(Year.now().getValue(), Month.DECEMBER, 25)));

3

如果目标只是为了在几天之内获得差异,并且由于上述答案中提到了有关委托方法的内容,则要指出,一次也可以简单地使用-

public long daysInBetween(java.time.LocalDate startDate, java.time.LocalDate endDate) {
  // Check for null values here

  return endDate.toEpochDay() - startDate.toEpochDay();
}

1
在陷入陷阱的陷阱中使用“ Period.between(date1,date2).getDays()”而没有意识到您松开了差异的月份和年份。
MrSmith42

2

获取两个日期之间的天date是java.util.Date的实例

public static long daysBetweenTwoDates(Date dateFrom, Date dateTo) {
            return DAYS.between(Instant.ofEpochMilli(dateFrom.getTime()), Instant.ofEpochMilli(dateTo.getTime()));
        }

1

我知道这个问题是针对Java 8的,但是对于Java 9,您可以使用:

public static List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
    return startDate.datesUntil(endDate)
      .collect(Collectors.toList());
}

0

使用最能满足您需求的类或方法:

  • 持续时间类,
  • 周期类,
  • ChronoUnit.between方法。

持续时间使用基于时间的值(秒,纳秒)来衡量时间量。

期间使用基于日期的值(年,月,日)。

当您只想在单个时间单位(例如天或秒)中测量时间量时,ChronoUnit.between方法很有用。

https://docs.oracle.com/javase/tutorial/datetime/iso/period.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.