如何在Java中获取两个日期之间的日期列表

88
  • 我需要一个包括起始日期和结束日期在内的日期列表。
  • 结果应该是一个包含所有日期的列表,包括起始日期和结束日期。

1
LocalDate.datesUntil() - ZhekaKozlov
1
对于那些使用Groovy(使用LocalDate)的人:(fromDate..toDate).each { println it } - lepe
24个回答

2
LocalDateRange”类在ThreeTen-Extra库中表示一个日期范围,可用于此目的。”
LocalDateRange.ofClosed(startDate, endDate).stream().toList();

2
一种解决方案是创建一个Calendar实例,并开始循环,增加其Calendar.DATE字段,直到达到所需的日期。 在每个步骤中,您应创建一个Date实例(具有相应的参数),并将其放入列表中。
一些糟糕的代码:
    public List<Date> getDatesBetween(final Date date1, final Date date2) {
    List<Date> dates = new ArrayList<Date>();

    Calendar calendar = new GregorianCalendar() {{
        set(Calendar.YEAR, date1.getYear());
        set(Calendar.MONTH, date1.getMonth());
        set(Calendar.DATE, date1.getDate());
    }};

    while (calendar.get(Calendar.YEAR) != date2.getYear() && calendar.get(Calendar.MONTH) != date2.getMonth() && calendar.get(Calendar.DATE) != date2.getDate()) {
        calendar.add(Calendar.DATE, 1);
        dates.add(new Date(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)));
    }

    return dates;
}

1
你知道你在使用一个已弃用的API吗?是啊,Java日期处理真糟糕。 - extraneon
我认为while循环的条件是“或”而不是“且”。 - Josue Martinez

2

从Java 9开始,你可以在LocalDate上使用datesUntil方法:

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

这个解决方案已经在Hochschild的答案中提到了。 - Basil Bourque
datesUntil方法不包括结束日期。由于问题要求也包含它,因此应该添加一个日期:startDate.datesUntil(endDate.plusDays(1)) - M. Justin

1

你也可以查看Date.getTime() API。它会返回一个长整型,你可以在上面加上你的增量。然后创建一个新的日期。

List<Date> dates = new ArrayList<Date>();
long interval = 1000 * 60 * 60; // 1 hour in millis
long endtime = ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
  dates.add(new Date(curTime));
  curTime += interval;
}

也许 Apache Commons 中的 DateUtils 有类似的功能,或者他们也可能有一个 CalendarUtils :)

编辑

如果您的间隔不完美,则包括开始日期和结束日期可能不可能 :)


1
这是一个获取日期列表的简单解决方案。
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;  
public class DateList
{

public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

 public static void main (String[] args) throws java.lang.Exception
 {

    Date dt = new Date();
    System.out.println(dt);

        List<Date> dates = getDates("2017-01-01",dateFormat.format(new Date()));
        //IF you don't want to reverse then remove Collections.reverse(dates);
         Collections.reverse(dates);
        System.out.println(dates.size());
    for(Date date:dates)
    {
        System.out.println(date);
    }
 }
 public static List<Date> getDates(String fromDate, String toDate)
 {
    ArrayList<Date> dates = new ArrayList<Date>();

    try {

        Calendar fromCal = Calendar.getInstance();
        fromCal.setTime(dateFormat .parse(fromDate));

        Calendar toCal = Calendar.getInstance();
        toCal.setTime(dateFormat .parse(toDate));

        while(!fromCal.after(toCal))
        {
            dates.add(fromCal.getTime());
            fromCal.add(Calendar.DATE, 1);
        }


    } catch (Exception e) {
        System.out.println(e);
    }
    return dates;
 }
}

请注意,旧的日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleTextFormat)现在已经成为遗留系统,被Java.time类所取代。请参阅Oracle教程。使用现代类可以更轻松地完成这项工作。 - Basil Bourque

1
使用Joda-Time,也许更好:
LocalDate dateStart = new LocalDate("2012-01-15");
LocalDate dateEnd = new LocalDate("2012-05-23");
// day by day:
while(dateStart.isBefore(dateEnd)){
    System.out.println(dateStart);
    dateStart = dateStart.plusDays(1);
}

这是我的解决方案...非常简单 :)

1
提醒一下,如果你使用 dateStart.isBefore( dateEnd ) 而不是 compareTo,那么代码可能会更易读。 - Basil Bourque

1
像@folone一样,但是正确的写法。
private static List<Date> getDatesBetween(final Date date1, final Date date2) {
    List<Date> dates = new ArrayList<>();
    Calendar c1 = new GregorianCalendar();
    c1.setTime(date1);
    Calendar c2 = new GregorianCalendar();
    c2.setTime(date2);
    int a = c1.get(Calendar.DATE);
    int b = c2.get(Calendar.DATE);
    while ((c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) || (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) || (c1.get(Calendar.DATE) != c2.get(Calendar.DATE))) {
        c1.add(Calendar.DATE, 1);
        dates.add(new Date(c1.getTimeInMillis()));
    }
    return dates;
}

为什么不使用before()after()方法来比较两个Calendar实例? - Alex Semeniuk

1
List<Date> dates = new ArrayList<Date>();
String str_date = "DD/MM/YYYY";
String end_date = "DD/MM/YYYY";
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date startDate = (Date)formatter.parse(str_date); 
Date endDate = (Date)formatter.parse(end_date);
long interval = 1000 * 60 * 60; // 1 hour in milliseconds
long endTime = endDate.getTime() ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();

while (curTime <= endTime) {
    dates.add(new Date(curTime));
    curTime += interval;
}
for (int i = 0; i < dates.size(); i++){
    Date lDate = (Date)dates.get(i);
    String ds = formatter.format(lDate);    
    System.out.println("Date is ..." + ds);
    //Write your code for storing dates to list
}

0

这将添加两个日期之间的所有日期,它将添加当前日期,然后根据循环条件添加新日期。

private void onDateSet(){
    Calendar endDate = Calendar.getInstance(),startDate = Calendar.getInstance();
    startDate.set(currentYear,currentMonthOfYear,currentDayOfMonth);
    endDate.set(inputYear,inputMonthOfYear,inputDayOfMonth);
    datesToAdd(startDate,endDate);
    }

    //call for get dates list
    private List<Date> datesToAdd(Calendar startDate,Calendar endDate){
                    List<Dates> datesLists = new List<>();
                    while (startDate.get(Calendar.YEAR) != endDate.get(Calendar.YEAR) ||   
                           startDate.get(Calendar.MONTH) != endDate.get(Calendar.MONTH) ||
                           startDate.get(Calendar.DAY_OF_MONTH) != endDate.get(Calendar.DAY_OF_MONTH)) {

                             datesList.add(new Date(startDate.get(Calendar.YEAR), startDate.get(Calendar.MONTH), startDate.get(Calendar.DATE));

                             startDate.add(Calendar.DATE, 1);//increas dates

                         }
                         return datesList;
                }

请注意,此代码使用现已过时的日期时间类,已被java.time类所取代。 - Basil Bourque
我没有使用java.time类,而是使用了 import java.util.Calendar; import java.util.Date; 我正在使用Java 8,一切都正常工作。 - ankurdayalsingh
不要使用 CalendarDate。它们现在已被 java.time 类所取代。那些旧类令人困惑、设计不良且存在缺陷。Sun、Oracle 和 JCP 社区都同意用 java.time 类替换这些遗留类;请参见 JSR 310。在2017年建议使用 DateCalendar 是不明智的。 - Basil Bourque

0

尾递归版本:

public static void datesBetweenRecursive(Date startDate, Date endDate, List<Date> dates) {
    if (startDate.before(endDate)) {
        dates.add(startDate);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.DATE, 1);
        datesBetweenRecursive(calendar.getTime(), endDate, dates);
    }
}

与Jules Rogerson的相同,但使用递归而不是迭代。 - Lluis Martinez

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