जावा में Dates की श्रेणी के माध्यम से पुनरावृति कैसे करें?


144

अपनी स्क्रिप्ट में मुझे तारीखों की श्रेणी के माध्यम से कार्यों का एक सेट करने की आवश्यकता है, एक शुरुआत और समाप्ति तिथि।
कृपया मुझे जावा का उपयोग करके इसे प्राप्त करने के लिए मार्गदर्शन प्रदान करें।

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

}

मुझे पता है कि उपरोक्त कोड बस असंभव है, लेकिन मैं आपको यह दिखाने के लिए करता हूं कि मैं क्या हासिल करना चाहता हूं।


जावा 8 और 9 स्वच्छ दृष्टिकोण: stackoverflow.com/a/51942109/1216775
akhil_mittal

जवाबों:


198

खैर, आप इस समस्या के लिए विशेष रूप से जावा 8 के टाइम-एपीआई का उपयोग करके कुछ ऐसा कर सकते हैं , java.time.LocalDate(या जावा 7 और पुराने के लिए समान जोडा टाइम कक्षाएं)

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

मैं होगा अच्छी तरह से उपयोग करने की अनुशंसा java.time(या Joda समय) में निर्मित से अधिक Date/ Calendarवर्गों।


2
जोडा टाइम के बारे में विस्तार करने के लिए: इसे सही ढंग से लागू करने की कोशिश करना मुश्किल है क्योंकि एक व्यक्ति सोच सकता है कि गर्मियों के समय से लेकर उसके आसपास के कोने के मामलों के कारण।
रायडवैल

Joda के लिए +1, मुझे उम्मीद है कि किसी दिन यह मानक API में भूमि तक पहुंच जाएगा।
गोर्यग्राभम

4
@gyabraham: JSR-310 जावा 8 के लिए बहुत अच्छे आकार में दिख रहा है
जॉन स्कीट

4
पुष्टि कर सकते हैं कि यह ठीक उसी कोड जावा के जावा जावा का उपयोग करके काम करेगा। Joda के बजाय।
पिघला हुआ आइस

3
जोडा-टाइम परियोजना अब रखरखाव मोड में है, और java.time कक्षाओं में प्रवास की सिफारिश करती है। जैसा कि टिप्पणियों में उल्लेख किया गया है, यह उत्तरदाता का कोड java.time में काम करता है, बस अपने importबयान बदलें ।
बेसिल बोर्के

146

हालांकि, संपूर्णता के लिए और / या यदि आप एपीआई प्रदान की गई सुविधाओं को पसंद करते हैं, तो यहाँ JodaTime अच्छा है, यहाँ मानक 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");

java.util.Calendarयदि आप अभी तक 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 का java.time.LocalDateदृष्टिकोण, मूल रूप से बिल्कुल JodaTime दृष्टिकोण:

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)क्रमशः।


75

जावा 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 ने डेट्स यूंटिल () विधि जोड़ी :

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

1
क्या आप कई गुना मान रख सकते हैं? केवल सोमवार या गुरुवार या दोनों: उदाहरण के लिए
delive

26

यह अनिवार्य रूप से वही उत्तर है जो बालूसी ने दिया था, लेकिन लूप के स्थान पर थोड़ी देर के लूप के साथ थोड़ा अधिक पठनीय है:

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

3
यह तब काम नहीं करेगा जब तर्क में "जारी" बयान शामिल हों, जबकि BalusC का लूप संस्करण जारी बयानों के साथ काम करता है।
संजीव जीवन

6

अपाचे कॉमन्स

    for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
        // ...
    }

जब आप पुराने कोड के साथ काम कर रहे हों तो +1, IMHO, यह सबसे साफ है। बस के लिए एक अतिरिक्त स्थिर आयात में फेंक addDays(..)और यह भी छोटा हो जाता है।
प्रियादु नीमरे

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

}

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

3

हम जावा 7, जावा 8 और जावा 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);

उत्पादन होगा:

[सोम दिसं २० ००:०० बजे २०१०, २१ दिसंबर २०० ००:०० IST २०१०, बुध २२ ००:०० बजे २०१०, २०१०, थु दिसम्बर २३ ००:००० २०१० २०१०, शुक्र दिसंबर २४००: 00:00 IST 2010, Sat Dec 25 00:00:00 IST 2010]

[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]


1
भयानक Dateऔर कक्षाएं सालों पहले java.time कक्षाओं Calendarद्वारा दबा दी गई थीं । विशेष रूप से, द्वारा प्रतिस्थापित Instantऔर ZonedDateDate
बेसिल बोर्क

1
मुझे जावा 8 और 9 तरीके पसंद हैं। जावा 6 और 7 के लिए मैं थ्रीटेन बैकपोर्ट लाइब्रेरी का उपयोग करने की सलाह देता हूं और फिर जावा 8. की तरह ही।
ओले वीवी

2

यहाँ जावा 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

यह सबसे अच्छा और आसान तरीका है जिसे आप फॉलो कर सकते हैं।
जतिन गोयल

1

क्यों नहीं आसानी से युग और पाश का उपयोग करें।

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

    }

1

आप इस पर एक वर्ग लिख सकते हैं (इटोमेर इंटरफ़ेस लागू करना) और उस पर पुनरावृति।

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

}

1

आप यह कोशिश कर सकते हैं:

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

0

यह आपको आज की तारीख तक 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());
        }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.