如何找到 startDate 和 endDate 之间的每周日期传递字符串,如动态传递的“Wed, Thu”

How to find every week dates between startDate and endDate passing string like " Wed, Thu" which is dynamically passed

当我将 startDate 和 endDate 与星期几一起传递时,如字符串“Mon ,Tue, Wed, Thu, Fri, Sat, Sun”,那么我希望每周的日期基于 startDate 和 endDate 之间经过的星期几.

从传入方法开始的天数可能是整周或自定义的一天。

1.My 尝试代码

public List<LocalDate> getWeeklyDateByStringofDays(String DaysofWeek, LocalDate startDate, LocalDate endDate) {
    List<String> daysOfWeekList = Arrays.asList(DaysofWeek.split(","));
    // How can do it no idea
}
  1. 获取您的 DaysOfWeek 输入字符串并将其解析为 List<DayOfWeek> 对象。例如,首先调用.split("\s*,\s*")得到一个包含MonTue等字符串数组。

  2. 把字符串"Mon"变成DayOfWeek.MONDAY。见下文。

  3. 创建一个 for 循环以遍历开始和结束之间的每个日期:for (LocalDate d = start; d.isBefore(end); d = d.plusDays(1))。每个日期,获取它代表的星期几,并检查它是否在您的列表中。

如何将“星期一”变成 DOW.MONDAY?

您可以制作自己的哈希图,将字符串映射到 DayOfWeek 值。或者,您可以依赖 java 的日期解析,但这有点棘手:

Locale where = Locale.forLanguageTag("en"); 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE", where);
TemporalAccessor accessor = formatter.parse("monday");
DayOfWeek dow = DayOfWeek.from(accessor);

当然,请注意您必须如何指定语言。毕竟,在地球上有很多表达 'monday' 的方式 :)

您可以按照以下方式进行:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getWeeklyDateByStringofDays("Mon, Tue, Wed", LocalDate.parse("2020-09-14"),
                LocalDate.parse("2020-12-14")));
    }

    static List<LocalDate> getWeeklyDateByStringofDays(String daysOfWeek, LocalDate startDate, LocalDate endDate) {
        // Split the string on optional whitespace followed by comma which in turn may
        // be followed by optional whitespace
        String[] daysOfWeekList = daysOfWeek.split("\s*,\s*");

        // The list to be populated with desired dates and returned
        List<LocalDate> result = new ArrayList<>();

        // Formatter to get only day name e.g. Mon from the date
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE", Locale.ENGLISH);

        for (String day : daysOfWeekList) {
            // Loop starting with the startDate until the endDate with a step of one day
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                if (date.format(dtf).equals(day)) {
                    result.add(date);
                }
            }
        }

        // Sort the list
        Collections.sort(result);

        return result;
    }
}

输出:

[2020-09-14, 2020-09-15, 2020-09-16, 2020-09-21, 2020-09-22, 2020-09-23, 2020-09-28, 2020-09-29, 2020-09-30, 2020-10-05, 2020-10-06, 2020-10-07, 2020-10-12, 2020-10-13, 2020-10-14, 2020-10-19, 2020-10-20, 2020-10-21, 2020-10-26, 2020-10-27, 2020-10-28, 2020-11-02, 2020-11-03, 2020-11-04, 2020-11-09, 2020-11-10, 2020-11-11, 2020-11-16, 2020-11-17, 2020-11-18, 2020-11-23, 2020-11-24, 2020-11-25, 2020-11-30, 2020-12-01, 2020-12-02, 2020-12-07, 2020-12-08, 2020-12-09, 2020-12-14]

注意:如果参数中的日期名称可以是任何大小写,请将上面给出的代码中的date.format(dtf).equals(day)替换为date.format(dtf).equalsIgnoreCase(day)

您可以从 LocalDate 中以三个字母的格式(例如 Mon)获取 DayOfWeek 并检查 daysOfWeek 中是否包含

localdate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US))

并使用 Stream.iterate 遍历范围,如果 LocalDateDayOfWeek 包含在您的 daysOfWeek 中,则进行过滤,然后在列表

中收集本地日期
  public List<LocalDate> getWeeklyDateByStringofDays(String daysOfWeek, LocalDate startDate,
      LocalDate endDate) {
    final int days = (int) startDate.until(endDate, ChronoUnit.DAYS);
    return Stream.iterate(startDate, d -> d.plusDays(1))
        .limit(days)
        .filter(d -> daysOfWeek.contains(d.getDayOfWeek()
                                          .getDisplayName(TextStyle.SHORT, Locale.US)))
        .collect(Collectors.toList());
  }