从列表中获取第一个后续 DayOfWeek

Get first subsequent DayOfWeek from list

对于日程应用程序,我需要从列表中确定今天之后的第一天,向前。例如:

DayOfWeek today -> SATURDAY
val list1 = listOf(MONDAY, TUESDAY, FRIDAY)

DayOfWeek today -> WEDNESDAY
val list2 = listOf(TUESDAY)

然后逻辑将不得不为列表 1 提供星期一,为列表 2 提供星期二。我知道 DayOfWeek 枚举 class 和 TemporalAdjusters.nextOrSame() 上的 .plusDays() 函数,但是你必须提供 DayOfWeek,我不知道,因为我正在尝试找到它在列表中。

    LocalDate today = LocalDate.now(ZoneId.systemDefault());
    List<DayOfWeek> list = List.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.FRIDAY);
    
    DayOfWeek first = Collections.min(list,
            Comparator.comparing(dow -> today.with(TemporalAdjusters.nextOrSame(dow))));
    System.out.println(first);

今天运行(我所在时区的星期六)时的输出:

MONDAY

我正在使用一个比较器查询最小值,该比较器比较一周中下一次出现的日期(如果今天恰好是那一天)。由于星期一排在第一位,因此这被视为最低限度。我间接调用了您在列表的每个成员中提到的 TemporalAdjusters.nextOrSame() 方法。这可能不是最省时的方法,但对于 20 个用途中的 19 个,我确信它没问题。而且它提供的代码很短而且我觉得可读,这更重要。

如果今天是星期三?让我们尝试将 today 设置为下周三:

    LocalDate today = LocalDate.of(2021, Month.JUNE, 23);

现在输出为:

FRIDAY

我来晚了,但我已经创建了一个解决方案。所以,发布它。

package com.ubaid;

import lombok.extern.slf4j.Slf4j;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class Demo {

    public static void main(String[] args) {

        List<DayOfWeek> list = List.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.FRIDAY);

        DayOfWeek nextDay = getFirstDayInListAfterTodayGoingForward(list);

        //will print MONDAY (today is SATURDAY)
        log.debug(String.valueOf(nextDay));

        list = List.of(DayOfWeek.TUESDAY);

        nextDay = getFirstDayInListAfterTodayGoingForward(list);
        //will print TUESDAY (today is SATURDAY)
        log.debug(String.valueOf(nextDay));
    }

    /**
     *
     * @param list of days of week
     * @return first day of week after today or today if today is present in the list
     */
    private static DayOfWeek getFirstDayInListAfterTodayGoingForward(List<DayOfWeek> list) {

        //MONDAY value is 1
        //  .
        //  .
        //SUNDAY value is 7

        //getting today value
        int todayVal = DayOfWeek.from(LocalDate.now()).getValue();

        //sort the DAYS according to their ordinal values
        List<Integer> daysInListVal = list
            .stream()
            .map(DayOfWeek::getValue)
            .sorted()
            .collect(Collectors.toList());

        if (daysInListVal.contains(todayVal)) {
            return DayOfWeek.of(todayVal);
        }

        //now get the DAY value which is next to today DAY
        //If next value is not present then pick the first item of sorted list
        return daysInListVal
            .stream()
            .filter(dayInList -> dayInList > todayVal)
            .findFirst()
            .map(DayOfWeek::of)
            .orElse(DayOfWeek.of(daysInListVal.stream().findFirst().orElseThrow()));
    }
}

这里是 ,作为函数翻译成 Kotlin。

fun nextWeekDayInList(list: List<DayOfWeek>, today: LocalDate) =
    list.minByOrNull { dow ->
        today.with(TemporalAdjusters.nextOrSame(dow))
    }

如果列表为空,这将 return null

用法:

println(nextWeekDayInList(
    listOf(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.FRIDAY),
    today = LocalDate.now(ZoneId.systemDefault())
))

来看,next可能比nextOrSame更合适。