Teleo
Teleo

Reputation: 11

Convert IntStream filter function for Java 7

Background: My application will not allow for me to bring in external libraries, though some may be accessible. I am working in Java 7. Disclaimer: This is my first Stack question.

My particular project is an effort to take 2 timestamps with just the local date pulled from them, where the first date is a record creation date and the second is a response date, then determine if the dates lay within my working days. I will later find the difference.

I'm already outside my depth by quite a bit, and so I need assistance 'translating' Java 8 code into Java 7.

I've searched some loosely related answers, but I'm struggling to grasp the fundamentals inherent to the concepts.

The primary code

        int allDaysBetween = (int) (ChronoUnit.DAYS.between(fromDay, toDay) + 1);
        long allWorkingMinutes = IntStream.range(0, allDaysBetween)
                .filter(i -> isWorkingDay(from.plusDays(i)))
                .count() * WORKING_MINUTES_PER_DAY ;

The supporting code

    private boolean isWorkingDay(final LocalDateTime time) {
        return time.getDayOfWeek().getValue() < DayOfWeek.SATURDAY.getValue();
    }

I'm simply in need of a functional equivalent. From my understanding, plusDays would add to my create date the time where my office is closed, so when I get the diff from my response date, I'll have an int with a smaller value.

The practical application is this:

Rather than include the weekend time, I want to exclude it so when I find the diff, I end up with the 'correct' number of minutes based on business hours.

Upvotes: 0

Views: 232

Answers (2)

Anonymous
Anonymous

Reputation: 86343

ThreeTen Backport

I am suggesting a library even though you said you could not use an external library (why not?), if only for the benefit of other readers. java.time has been backported. So you can use the same date/time types on Java 7. Only the stream operation is not available (there might be a library for something similar, I don’t know). So I am using a classical loop instead.

    LocalDateTime fromDay = LocalDateTime.of(2019, Month.APRIL, 12, 0, 0);
    LocalDateTime toDay = LocalDateTime.of(2019, Month.APRIL, 16, 0, 0);
    int allDaysBetween = 0;
    for (LocalDate d = fromDay.toLocalDate(); ! d.isAfter(toDay.toLocalDate()); d = d.plusDays(1)) {
        if (isWorkingDay(d)) {
            allDaysBetween++;
        }
    }
    long allWorkingMinutes = allDaysBetween * WORKING_MINUTES_PER_DAY;
    System.out.println(allWorkingMinutes);

I have added threetenbp-1.3.6.jar and threetenbp-1.3.6-javadoc.jar to my project (I believe that newer versions exist) and am using the following imports:

import org.threeten.bp.DayOfWeek;
import org.threeten.bp.Duration;
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.Month;
import org.threeten.bp.temporal.ChronoUnit;

I changed your supporting method, isWorkingDay, to take a LocalDate argument because I found it convenient, it would work in your version too.

You may want to challenge the decision? If that’s a project decision not to use an external library, you may want to challenge that. You may argue that ThreeTen Backport is not really external since it’s a backport of core Java functionality. And you will need the library only until one day you move on to Java 8 or later.

Links

Upvotes: 0

Andreas
Andreas

Reputation: 159165

The following Java 8+ stream code:

long allWorkingMinutes = IntStream.range(0, allDaysBetween)
        .filter(i -> isWorkingDay(from.plusDays(i)))
        .count() * WORKING_MINUTES_PER_DAY ;

Is the same as this general code that will work in any Java version:

long count = 0;
for (int i = 0; i < allDaysBetween; i++)
    if (isWorkingDay(from.plusDays(i)))
        count++;
long allWorkingMinutes = count * WORKING_MINUTES_PER_DAY ;

As for the ChronoUnit, LocalDateTime, and DayOfWeek classes, use the ThreeTen Backport for Java SE 6 and 7 support.

Upvotes: 4

Related Questions