programing

Java에서 날짜 범위를 반복하는 방법

randomtip 2022. 11. 1. 22:11
반응형

Java에서 날짜 범위를 반복하는 방법

스크립트에서는 시작일과 종료일이 지정된 날짜 범위 내에서 일련의 작업을 수행해야 합니다.
Java를 사용하여 이를 실현하기 위한 가이던스를 부탁드립니다.

for ( currentDate = starDate; currentDate < endDate; currentDate++) {

}

위의 코드가 단순히 불가능하다는 것을 알지만, 제가 이루고 싶은 것을 보여드리기 위해 그렇게 합니다.

Java 8의 Time-API를 사용하여 이 문제를 해결할 수 있습니다(또는 Java 7 이전 버전에서는 동등한 Joda Time 클래스).

for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
    ...
}

이 기능을 사용하는 것을 강력히 권장합니다.java.time(또는 Joda Time) 기본 제공 기간 동안Date/Calendar반.

단, Joda Time은 완전성을 위해 좋으며 API 제공 설비를 원하는 경우 표준 API 접근방식을 소개합니다.

로 시작하는 경우java.util.Date다음과 같은 인스턴스:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");

Java8을 아직 사용하지 않은 경우의 레거시 접근법은 다음과 같습니다.

Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);

for (Date date = start.getTime(); start.before(end); start.add(Calendar.DATE, 1), date = start.getTime()) {
    // Do your job here with `date`.
    System.out.println(date);
}

Java8의 접근방식은 기본적으로 Joda Time 접근방식입니다.

LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) {
    // Do your job here with `date`.
    System.out.println(date);
}

종료일을 포함하여 반복하고 싶다면!start.after(end)그리고.!date.isAfter(end)각각 다음과 같다.

Java 8 스타일(java.time 클래스 사용):

// Monday, February 29 is a leap day in 2016 (otherwise, February only has 28 days)
LocalDate start = LocalDate.parse("2016-02-28"),
          end   = LocalDate.parse("2016-03-02");

// 4 days between (end is inclusive in this example)
Stream.iterate(start, date -> date.plusDays(1))
        .limit(ChronoUnit.DAYS.between(start, end) + 1)
        .forEach(System.out::println);

출력:

2016-02-28
2016-02-29
2016-03-01
2016-03-02

다른 방법:

LocalDate next = start.minusDays(1);
while ((next = next.plusDays(1)).isBefore(end.plusDays(1))) {
    System.out.println(next);
}

Java 9가 날짜를 추가했습니다.Til() 메서드:

start.datesUntil(end.plusDays(1)).forEach(System.out::println);

이는 기본적으로 BalusC가 제시한 답변과 동일하지만 for 루프 대신 while loop을 사용하면 읽기 쉬울 수 있습니다.

Calendar start = Calendar.getInstance();
start.setTime(startDate);

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

while( !start.after(end)){
    Date targetDay = start.getTime();
    // Do Work Here

    start.add(Calendar.DATE, 1);
}

아파치 커먼즈

    for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
        // ...
    }
private static void iterateBetweenDates(Date startDate, Date endDate) {
    Calendar startCalender = Calendar.getInstance();
    startCalender.setTime(startDate);
    Calendar endCalendar = Calendar.getInstance();
    endCalendar.setTime(endDate);

    for(; startCalender.compareTo(endCalendar)<=0;
          startCalender.add(Calendar.DATE, 1)) {
        // write your main logic here
    }

}

로직을 Java 7, Java 8, Java 9에 대해 다양한 방법으로 이행할 수 있습니다.

public static List<Date> getDatesRangeJava7(Date startDate, Date endDate) {
    List<Date> datesInRange = new ArrayList<>();
    Calendar startCalendar = new GregorianCalendar();
    startCalendar.setTime(startDate);
    Calendar endCalendar = new GregorianCalendar();
    endCalendar.setTime(endDate);
    while (startCalendar.before(endCalendar)) {
        Date result = startCalendar.getTime();
        datesInRange.add(result);
        startCalendar.add(Calendar.DATE, 1);
    }
    return datesInRange;
}

public static List<LocalDate> getDatesRangeJava8(LocalDate startDate, LocalDate endDate) {
    int numOfDays = (int) ChronoUnit.DAYS.between(startDate, endDate);
    return IntStream.range(0, numOfDays)
            .mapToObj(startDate::plusDays)
            .collect(Collectors.toList());
}

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

다음으로, 다음의 메서드를 호출할 수 있습니다.

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");
List<Date> dateRangeList = getDatesRangeJava7(startDate, endDate);
System.out.println(dateRangeList);

LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
List<LocalDate> dateRangeList8 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList8);
List<LocalDate> dateRangeList9 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList9);

출력은 다음과 같습니다.

[2010년 12월 20일 (월) 00:00:00:00 IST 2010년 12월 22일 (수) 00:00:00:00 IST 2010년 12월 23일 (목) 00:00:00:00 IST 2010년 IST 2010년 12월 24일 (금) 00:00:00:00:00 IST 2010년 IST 2010년 12월 25일 (토)

[2010-12-20, 2010-12-21, 2010-12-22, 2010-12-23, 2010-12-24, 2010-12-25]

[2010-12-20, 2010-12-21, 2010-12-22, 2010-12-23, 2010-12-24, 2010-12-25]

내장: Java 9 이후 LocalDate.datesEntil()

지금까지의 답변은 Java 8 이전 버전만을 검토했던 것 같습니다.Java 9+ 방법은 다음과 같습니다.

    LocalDate startDate = LocalDate.of(2021, Month.JUNE, 29);
    LocalDate endDate = LocalDate.of(2021, Month.JULY, 3);
    
    startDate.datesUntil(endDate).forEach(System.out::println);

이 예의 출력은 다음과 같습니다.

2021-06-29
2021-06-30
2021-07-01
2021-07-02

시작 날짜는 포함되지만 종료 날짜는 제가 읽은 질문에서와 같이 제외됩니다.종료일을 포함시키고 싶은 경우는, 간단하게 하루를 추가할 수 있습니다.

    startDate.datesUntil(endDate.plusDays(1)).forEach(System.out::println);
2021-06-29
2021-06-30
2021-07-01
2021-07-02
2021-07-03

으로 몇 할 수 하면 더 긴할 수 . 하면 를 할 수 . 마치 더 긴 람다를 제가 방금 방법 참조를 넣은 곳에 넣을 수 있는 것처럼요.System.out::println데모를 위해.

링크

public static final void generateRange(final Date dateFrom, final Date dateTo)
{
    final Calendar current = Calendar.getInstance();
    current.setTime(dateFrom);

    while (!current.getTime().after(dateTo))
    {
        // TODO

        current.add(Calendar.DATE, 1);
    }
}

Java 8 코드입니다.이 코드가 당신의 문제를 해결해 줄 것 같습니다.해피 코딩

    LocalDate start = LocalDate.now();
    LocalDate end = LocalDate.of(2016, 9, 1);//JAVA 9 release date
    Long duration = start.until(end, ChronoUnit.DAYS);
    System.out.println(duration);
     // Do Any stuff Here there after
    IntStream.iterate(0, i -> i + 1)
             .limit(duration)
             .forEach((i) -> {});
     //old way of iteration
    for (int i = 0; i < duration; i++)
     System.out.print("" + i);// Do Any stuff Here

Epoch를 사용하여 쉽게 루프를 통과해 보는 것은 어떨까요?

long startDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(startDate).getTime() / 1000;

    long endDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(endDate).getTime() / 1000;


    long i;
    for(i=startDateEpoch ; i<=endDateEpoch; i+=86400){

        System.out.println(i);

    }

이와 같은 클래스(반복기 인터페이스 구현)를 작성하여 반복할 수 있습니다.

public class DateIterator implements Iterator<Date>, Iterable<Date>
{

 private Calendar end = Calendar.getInstance();
 private Calendar current = Calendar.getInstance();

 public DateIterator(Date start, Date end)
 {
     this.end.setTime(end);
     this.end.add(Calendar.DATE, -1);
     this.current.setTime(start);
     this.current.add(Calendar.DATE, -1);
 }

 @Override
 public boolean hasNext()
 {
     return !current.after(end);
 }

 @Override
 public Date next()
 {
     current.add(Calendar.DATE, 1);
     return current.getTime();
 }

 @Override
 public void remove()
 {
     throw new UnsupportedOperationException(
        "Cannot remove");
 }

 @Override
 public Iterator<Date> iterator()
 {
     return this;
 }
}

다음과 같이 사용합니다.

Iterator<Date> dateIterator = new DateIterator(startDate, endDate);
while(dateIterator.hasNext()){
      Date selectedDate = dateIterator .next();

}

다음과 같이 시험해 보십시오.

OffsetDateTime currentDateTime = OffsetDateTime.now();
for (OffsetDateTime date = currentDateTime; date.isAfter(currentDateTime.minusYears(YEARS)); date = date.minusWeeks(1))
{
    ...
}

그러면 30일 전에 시작하여 오늘 날짜까지 루프스루 할 수 있습니다.날짜와 방향의 범위를 쉽게 변경할 수 있습니다.

private void iterateThroughDates() throws Exception {
    Calendar start = Calendar.getInstance();
    start.add(Calendar.DATE, -30);
    Calendar end = Calendar.getInstance();
    for (Calendar date = start; date.before(end); date.add(Calendar.DATE, 1))
        {
        System.out.println(date.getTime());
        }
}

다음 스니펫(Java.time.format of Java 8 사용)은 날짜 범위에 걸쳐 반복할 때 사용될 수 있습니다.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    // Any chosen date format maybe taken  
    LocalDate startDate = LocalDate.parse(startDateString,formatter);
    LocalDate endDate = LocalDate.parse(endDateString,formatter);
    if(endDate.isBefore(startDate))
    {
        //error
    }
    LocalDate itr = null;
    for (itr = startDate; itr.isBefore(endDate)||itr.isEqual(itr); itr = itr.plusDays(1))
    {
        //Processing  goes here
    }

plusMonths()/plusYears()는 시간 단위 증분으로 선택될 수 있습니다.위 그림에서는 하루 단위로 증분이 이루어지고 있습니다.

언급URL : https://stackoverflow.com/questions/4534924/how-to-iterate-through-range-of-dates-in-java

반응형