UFO ET IT

자바에서 두 날짜 사이의 날짜 목록을 얻는 방법

ufoet 2020. 12. 2. 22:18
반응형

자바에서 두 날짜 사이의 날짜 목록을 얻는 방법


시작일과 종료일 사이의 날짜 목록을 원합니다.

결과는 시작일과 종료일을 포함한 모든 날짜의 목록이어야합니다.


2010 년에 저는 Joda-Time 을 사용하도록 제안 했습니다.

Joda-Time은 이제 유지 관리 모드에 있습니다. 1.8 (2014)부터 java.time.

종료일에 도달 할 때까지 한 번에 1 일 추가 :

int days = Days.daysBetween(startDate, endDate).getDays();
List<LocalDate> dates = new ArrayList<LocalDate>(days);  // Set initial capacity to `days`.
for (int i=0; i < days; i++) {
    LocalDate d = startDate.withFieldAdded(DurationFieldType.days(), i);
    dates.add(d);
}

이 작업을 수행하기 위해 자체 반복기를 구현하는 것도 그리 어렵지 않을 것입니다.


java.time 패키지

Java 8을 사용 하는 경우 훨씬 더 깔끔한 접근 방식이 있습니다. Java 8 의 새로운 java.time 패키지Joda-Time API 의 기능을 통합합니다 .

아래 코드를 사용하여 요구 사항을 해결할 수 있습니다.

String s = "2014-05-01";
String e = "2014-05-10";
LocalDate start = LocalDate.parse(s);
LocalDate end = LocalDate.parse(e);
List<LocalDate> totalDates = new ArrayList<>();
while (!start.isAfter(end)) {
    totalDates.add(start);
    start = start.plusDays(1);
}

날짜 사이의 일 수를 가져옵니다.

public static List<Date> getDaysBetweenDates(Date startdate, Date enddate)
{
    List<Date> dates = new ArrayList<Date>();
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(startdate);

    while (calendar.getTime().before(enddate))
    {
        Date result = calendar.getTime();
        dates.add(result);
        calendar.add(Calendar.DATE, 1);
    }
    return dates;
}

스트림

편집 : Joda-Time은 이제 더 이상 사용되지 않으며 대신 Java 8을 사용하도록 답변을 변경했습니다.

다음은 스트림을 사용하는 Java 8 방식입니다.

List<LocalDate> daysRange = Stream.iterate(startDate, date -> date.plusDays(1)).limit(numOfDays).collect(Collectors.toList());

아래 코드를 찾으십시오.

List<Date> dates = new ArrayList<Date>();

String str_date ="27/08/2010";
String end_date ="02/09/2010";

DateFormat formatter ; 

formatter = new SimpleDateFormat("dd/MM/yyyy");
Date  startDate = (Date)formatter.parse(str_date); 
Date  endDate = (Date)formatter.parse(end_date);
long interval = 24*1000 * 60 * 60; // 1 hour in millis
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);
}

산출:

날짜는 ... 27/08/2010
날짜는 ... 28/08/2010
날짜는 ... 29/08/2010
날짜는 ... 30/08/2010
날짜는 ... 31/08/2010
날짜는 ... 01/09/2010
날짜는 ... 02/09/2010


추천 날짜 스트림

Java 9 에서는 다음과 같은 새로운 방법을 사용할 수 있습니다 LocalDate::datesUntil.

LocalDate start = LocalDate.of(2017, 2, 1);
LocalDate end = LocalDate.of(2017, 2, 28);

Stream<LocalDate> dates = start.datesUntil(end.plusDays(1));
List<LocalDate> list = dates.collect(Collectors.toList());

새로운 방법 datesUntil(...)은 독점적 인 종료 날짜로 작동하므로 표시된 해킹은 하루를 추가합니다.

스트림을 얻으면 java.util.stream-또는- java.util.function패키지에서 제공하는 모든 기능을 이용할 수 있습니다 . 스트림 작업은 사용자 정의 된 for 또는 while 루프를 기반으로 한 이전 접근 방식에 비해 매우 간단 해졌습니다.


또는 기본적으로 포함 날짜에서 작동하지만 다른 방식으로 구성 할 수도있는 스트림 기반 솔루션을 찾는 경우 성능 분할기를 포함하여 날짜 스트림과 관련된 많은 특수 기능을 제공하기 때문에 내 라이브러리 Time4J 에서 DateInterval 클래스가 흥미로울 수 있습니다. Java-9보다 빠릅니다.

PlainDate start = PlainDate.of(2017,  2, 1);
PlainDate end = start.with(PlainDate.DAY_OF_MONTH.maximized());
Stream<PlainDate> stream = DateInterval.streamDaily(start, end);

또는 전체 개월의 경우 더 간단합니다.

Stream<PlainDate> februaryDates = CalendarMonth.of(2017, 2).streamDaily();
List<LocalDate> list = 
    februaryDates.map(PlainDate::toTemporalAccessor).collect(Collectors.toList());

이와 같은 것이 확실히 작동합니다.

private List<Date> getListOfDaysBetweenTwoDates(Date startDate, Date endDate) {
    List<Date> result = new ArrayList<Date>();
    Calendar start = Calendar.getInstance();
    start.setTime(startDate);
    Calendar end = Calendar.getInstance();
    end.setTime(endDate);
    end.add(Calendar.DAY_OF_YEAR, 1); //Add 1 day to endDate to make sure endDate is included into the final list
    while (start.before(end)) {
        result.add(start.getTime());
        start.add(Calendar.DAY_OF_YEAR, 1);
    }
    return result;
}

Lamma를 사용하면 Java에서 다음과 같이 보입니다.

    for (Date d: Dates.from(2014, 6, 29).to(2014, 7, 1).build()) {
        System.out.println(d);
    }

출력은 다음과 같습니다.

    Date(2014,6,29)
    Date(2014,6,30)
    Date(2014,7,1)

한 가지 해결책은 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;
}

 public static List<Date> getDaysBetweenDates(Date startDate, Date endDate){
        ArrayList<Date> dates = new ArrayList<Date>();
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(startDate);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(endDate);

        while(cal1.before(cal2) || cal1.equals(cal2))
        {
            dates.add(cal1.getTime());
            cal1.add(Calendar.DATE, 1);
        }
        return dates;
    }

Java 8 사용

public Stream<LocalDate> getDaysBetween(LocalDate startDate, LocalDate endDate) {
    return IntStream.range(0, (int) DAYS.between(startDate, endDate)).mapToObj(startDate::plusDays);
}

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;
}

그리고 아마도 아파치 커먼즈는 DateUtils에서 이와 같은 것을 가지고 있거나 아마도 CalendarUtils도 가지고 있습니다 :)

편집하다

간격이 완벽하지 않으면 시작일 종료일을 포함 하지 못할 수 있습니다. :)


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
}

@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;
}

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);
}

그것은 내 솔루션입니다 .... 매우 쉽습니다 :)


꼬리 재귀 버전 :

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);
    }
}

위의 솔루션 중 하나를 개선합니다. 종료일에 1 일을 추가하면 때때로 종료일보다 더 많은 날이 추가됩니다.


    public static List getDaysBetweenDates (Date startdate, Date enddate)
    {
        날짜 나열 = new ArrayList ();
        달력 startDay = new GregorianCalendar ();
        calendar.setTime (시작일);
        달력 endDay = new GregorianCalendar ();
        endDay.setTime (enddate);
        endDay.add (Calendar.DAY_OF_YEAR, 1);
        endDay.set (Calendar.HOUR_OF_DAY, 0);
        endDay.set (Calendar.MINUTE, 0);
        endDay.set (Calendar.SECOND, 0);
        endDay.set (Calendar.MILLISECOND, 0);

        while (calendar.getTime (). before (endDay.getTime ())) {
            날짜 결과 = startDay.getTime ();
            date.add (결과);
            startDay.add (Calendar.DATE, 1);
        }
        반환 날짜;
    }


다음은 영업일을 포함하여 / wo를 포함하여 두 날짜 사이의 날짜를 얻는 방법입니다. 또한 소스 및 원하는 날짜 형식을 매개 변수로 사용합니다.

public static List<String> getAllDatesBetweenTwoDates(String stdate,String enddate,String givenformat,String resultformat,boolean onlybunessdays) throws ParseException{
        DateFormat sdf;
        DateFormat sdf1;
        List<Date> dates = new ArrayList<Date>();
        List<String> dateList = new ArrayList<String>();
          SimpleDateFormat checkformat = new SimpleDateFormat(resultformat); 
          checkformat.applyPattern("EEE");  // to get Day of week
        try{
            sdf = new SimpleDateFormat(givenformat);
            sdf1 = new SimpleDateFormat(resultformat);
            stdate=sdf1.format(sdf.parse(stdate));
            enddate=sdf1.format(sdf.parse(enddate));

            Date  startDate = (Date)sdf1.parse( stdate); 
            Date  endDate = (Date)sdf1.parse( enddate);
            long interval = 24*1000 * 60 * 60; // 1 hour in millis
            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 = sdf1.format(lDate);   
                if(onlybunessdays){
                    String day= checkformat.format(lDate); 
                    if(!day.equalsIgnoreCase("Sat") && !day.equalsIgnoreCase("Sun")){
                          dateList.add(ds);
                    }
                }else{
                      dateList.add(ds);
                }

                //System.out.println(" Date is ..." + ds);

            }


        }catch(ParseException e){
            e.printStackTrace();
            throw e;
        }finally{
            sdf=null;
            sdf1=null;
        }
        return dateList;
    }

메서드 호출은 다음과 같습니다.

public static void main(String aregs[]) throws Exception {
        System.out.println(getAllDatesBetweenTwoDates("2015/09/27","2015/10/05","yyyy/MM/dd","dd-MM-yyyy",false));
    }

데모 코드를 찾을 수 있습니다. 여기를 클릭하십시오.


List<LocalDate> totalDates = new ArrayList<>();
popularDatas(startDate, endDate, totalDates);
System.out.println(totalDates);

private void popularDatas(LocalDate startDate, LocalDate endDate, List<LocalDate> datas) {
    if (!startDate.plusDays(1).isAfter(endDate)) {
        popularDatas(startDate.plusDays(1), endDate, datas);
    } 
    datas.add(startDate);
}

재귀 솔루션


이것은 날짜 목록을 얻는 간단한 솔루션입니다.

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;
 }
}

이것은 두 날짜 사이의 모든 날짜를 추가하고 현재 날짜를 추가 한 다음 루프 조건에 따라 새 날짜를 추가합니다.

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;
                }

이렇게 계산할 수있는 java9 기능

public  List<LocalDate> getDatesBetween (
 LocalDate startDate, LocalDate endDate) {

   return startDate.datesUntil(endDate)
     .collect(Collectors.toList());
}
`` 


참고 URL : https://stackoverflow.com/questions/2689379/how-to-get-a-list-of-dates-between-two-dates-in-java

반응형