3

I am using Java 8, i need to count how many days we have in an interval having index = x. Example: from 1-1-2019 till 31-1-2019 we have 1 occurrence of Day 1.

I do not want the range of days, just the count of day X If its the last day of month, i want to count them all example: 30 +30 +31+28

user666
  • 1,750
  • 3
  • 18
  • 34
  • what do you mean by 1? is it the 1st day of every month? – Mustahsan Mar 01 '19 at 07:05
  • Could you share some of the relevant code? What do you mean by "having index = x"? – TiiJ7 Mar 01 '19 at 07:05
  • Possible duplicate of [Determine number of days represented by a time range in Java](https://stackoverflow.com/questions/41833781/determine-number-of-days-represented-by-a-time-range-in-java) – Duong Anh Mar 01 '19 at 07:06
  • how would you want the code to react when given as input the day of 31, and the interval of a whole year? would the answer be 7? – Claudiu Guja Mar 01 '19 at 07:08
  • index means either first of the month, or last day or any day in between. It is a variable. – user666 Mar 01 '19 at 07:13
  • So if index is 31 and the range is the whole year, will the answer be 7 or not? – Sweeper Mar 01 '19 at 07:15
  • 2
    What have you tried yourself? Please add your code to the question. – Joakim Danielson Mar 01 '19 at 07:21
  • if its end of month we will count all of them means 12 in a year. I have a way with no loop but its error prone, i am still trying to find the optimal solution. Will post it when done. The first way was to get the first and then the last occurrences and then using the Java 8 months.between. But the occurrences must be within the range, and this does not cover the last day of month dilemma – user666 Mar 01 '19 at 08:06

5 Answers5

4

try this method:

public static int getDateCount(LocalDate startDate, LocalDate endDate, final int index) {
        long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
        return IntStream.iterate(0, i -> i + 1)
                .limit(numOfDaysBetween)
                .mapToObj(i -> startDate.plusDays(i))
                .filter(i -> i.getDayOfMonth() == index)
                .collect(Collectors.toList()).size();
    }

usage:

public static void main(String[] args){
        LocalDate startDate = LocalDate.of(2019,1,1);
        LocalDate endDate = LocalDate.of(2019,1,31);
        int index=1;

        System.out.println(getDateCount(startDate,endDate,index));
    }

output:

1

Here i first calculated days between two dates then extracted all days occuring between these dates then filtered them to desired day e.g 1 in that case.

Note : that might not be the best and effective solution

Mustahsan
  • 3,852
  • 1
  • 18
  • 34
  • using parallel stream can improve performance but i am also trying to achieve it with some other possible way, as soon as i figure it out i will update it here – Mustahsan Mar 01 '19 at 07:55
0

I don't know if the java.time API provides methods to directly do this, but you can always loop through all the dates between the start and end check them one by one.

LocalDate start = LocalDate.of(2019, 1, 1);
LocalDate end = LocalDate.of(2022, 12, 31);
long daysBetween = ChronoUnit.DAYS.between(start, end);
System.out.println(daysBetween);
// you might want to use a parallel stream. It might speed things up a little
long count = LongStream.range(0, daysBetween + 1)
                 .mapToObj(start::plusDays)
                 .filter(x -> x.getDayOfMonth() == index)
                 .count();
System.out.println(count);

There is a special case for the last day of the month, you need:

.filter(x -> x.equals(x.with(TemporalAdjusters.lastDayOfMonth())))
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

here is the solution:

    LocalDate start = LocalDate.of(2019, 1, 1);
    LocalDate end = LocalDate.of(2019, 3, 31);
    long daysBetween = ChronoUnit.DAYS.between(start, end);

    int index = 1;
    int count = 0;
    start = start.minusDays(1);
    for(int i = 0; i <= daysBetween; i++){
        start = start.plusDays(1);
        if (start.getDayOfMonth() == index) {
            count++;
        }
    }
    System.out.println(count);
X.Bing
  • 12
  • 4
0

finding days in-between using:

Days d = Days.daysBetween(startDate, endDate); int days = d.getDays();

finding specific day was there or not, suppose 11th of month.

(startDay + days) contains the day you require something like that.

Mustahsan
  • 3,852
  • 1
  • 18
  • 34
SBD
  • 126
  • 1
  • 6
0
    public long getNumberOfDayOfMonthBetweenDates(LocalDate startDate, LocalDate endDate, int dayOfMonth) {
    long result = -1;
    if (startDate != null && endDate != null && dayOfMonth > 0 && dayOfMonth < 32) {
        result = 0;
        LocalDate startDay = getDayInCurrentMonth(startDate, dayOfMonth);
        // add one day as end date is exclusive
        // add + 1 to cover higher possibilities (month and a half or half month or so)
        long totalMonths = ChronoUnit.MONTHS.between(startDate, endDate.plusDays(1)) + 2;
        for (int i = 0; i < totalMonths; i++) {
            if ((!startDay.isBefore(startDate) && startDay.isBefore(endDate)) || startDay.equals(startDate) || startDay.equals(endDate)) {
                result++;
            }
            startDay = getDayInCurrentMonth(startDay.plusMonths(1), dayOfMonth);
        }
    }
    return result;
}

private LocalDate getDayInCurrentMonth(LocalDate startDate, int dayOfMonth) {
    LocalDate dayOfThisMonth;
    try {
        dayOfThisMonth = startDate.withDayOfMonth(dayOfMonth);
    } catch (DateTimeException e) {
        // handle cases where current month does not contain the given day (example 30 in Feb)
        dayOfThisMonth = startDate.withDayOfMonth(startDate.lengthOfMonth());
    }
    return dayOfThisMonth;
}
user666
  • 1,750
  • 3
  • 18
  • 34