Remo
Remo

Reputation: 604

How to get List of DayOfWeek from between two DayOfWeeks

I want to get the list of DayOfWeeks, between two DayOfWeeks.

For example,

Input1: DayOfWeek.MONDAY
Input2: DayOfWeek.WEDNESDAY

And output should be list

[DayOfWeek.MONDAY, DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY]

Is Java providing any Api to achieve this?

Upvotes: 4

Views: 876

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 338775

tl;dr

EnumSet.range( DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY )

EnumSet.range

EnumSet is an implementation of Set optimized for working with enum objects.

EnumSet.range creates a subset of the enum’s objects in the order of their definition. For DayOfWeek, that order is Monday-Sunday, per the ISO 8601 standard.

The range is fully-closed, meaning both the beginning and the ending are inclusive.

Set<DayOfWeek> set = EnumSet.range( DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY );

set.toString(): [MONDAY, TUESDAY, WEDNESDAY]

If your problem domain uses an order of days different than Monday-Sunday, see the Answer by Ole V.V.

If you really need a List rather than a Set, convert. Feed the set to the constructor of a List implementation such as ArrayList.

List< DayOfWeek > dows = new ArrayList<>( set );

Upvotes: 1

Anonymous
Anonymous

Reputation: 86296

Crossing the week boundary

The other answers are good (I particularly like Basil Bourque’s EnumSet solution). They all seem to presuppose (1) that your two input days are in the same week, and (2) that the week begins on Monday as the DayOfWeek enum does. Now what if inputs were Friday and Monday, wouldn’t we want Friday, Saturday, Sunday, Monday? What if the user in the USA and expects that Sunday and Tuesday yields Sunday, Monday, Tuesday? Sunday is the first day of the week there (and in some other places too).

I think that taking these possibilities into account there is no better solution than a classical loop.

    DayOfWeek input1 = DayOfWeek.FRIDAY;
    DayOfWeek input2 = DayOfWeek.MONDAY;

    List<DayOfWeek> range = new ArrayList<>(7);
    DayOfWeek currentDow = input1;
    range.add(currentDow);
    while (! currentDow.equals(input2)) {
        currentDow = currentDow.plus(1);
        range.add(currentDow);
    }

    System.out.println(range);

Output:

[FRIDAY, SATURDAY, SUNDAY, MONDAY]

Since I am using a list rather than a set, the days come in order. Fortunately the plus method has cyclic overflow: SUNDAY.plus(1) yields MONDAY, the first enum member.

Not crossing the week boundary

If it’s a requirement that you are not crossing into the following week (from Sunday to Monday), you should check that your inputs fulfill the requirement and then use one of the other answers. Example check:

    if (input1.getValue() > input2.getValue()) {
        throw new IllegalStateException("Inputs muct be in chronological order within the same Monday-based week");
    }

Upvotes: 2

Ryuzaki L
Ryuzaki L

Reputation: 40058

You can get days using DayOfWeek.values() and then use filter to filter the days between MONDAY and WEDNESDAY

List<DayOfWeek> days = Arrays.stream(DayOfWeek.values())
            .filter(day -> day.getValue() >= DayOfWeek.MONDAY.getValue()
                    && day.getValue() <= DayOfWeek.WEDNESDAY.getValue())
            .collect(Collectors.toList());

    System.out.println(days);

Upvotes: 4

Jason
Jason

Reputation: 5246

This is one way you can achieve it. There may be a better way. You create a Stream of Integer values where the start is the first day and the last is the last day + 1. Then map the DayOfWeek object in respect to the day value.

        DayOfWeek monday = DayOfWeek.MONDAY;

        DayOfWeek wednesday = DayOfWeek.WEDNESDAY;

        List<DayOfWeek> days = IntStream.range(monday.getValue(), wednesday.getValue() + 1)
                .mapToObj(DayOfWeek::of)
                .collect(Collectors.toList());

Output

[MONDAY, TUESDAY, WEDNESDAY]

Upvotes: 1

Related Questions