-1

when i passing startDate and endDate with day of week like as string "Mon ,Tue, Wed, Thu, Fri, Sat, Sun" then i want date of every weekly based on passing day of week between startDate and endDate.

Days is may be fully week or custom day from passing into method.

1.My try code

public List<LocalDate> getWeeklyDateByStringofDays(String DaysofWeek, LocalDate startDate, LocalDate endDate) {
    List<String> daysOfWeekList = Arrays.asList(DaysofWeek.split(","));
    // How can do it no idea
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Could you please provide a sample input and the expected output? It is not entirely clear to me what you're exactly trying to achieve – Lino Sep 14 '20 at 07:42
  • Do you want every `LocalDate` of every day of week passed within the given range? – deHaar Sep 14 '20 at 07:43
  • To parse a String as abbreviated weekday, you can use a [`DateTimeFormatter`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/time/format/DateTimeFormatter.html) with the appropriate number of repetitions of pattern `E` (or perhaps `e`, depending on your localization requirements) – Hulk Sep 14 '20 at 07:44
  • yes, by passing days like String "Mon, Tue". then i want every of that date which i pass as String between date range – Techavidus User Sep 14 '20 at 07:46
  • 1
    @Lino this is sample input String like "Mon, Tue, Wed" startDate = 2020-09-14 and endDate = 2020-12-14 – Techavidus User Sep 14 '20 at 07:48

3 Answers3

3

You can get DayOfWeek from LocalDate in the format of three letters(e.g.Mon) and check contains in daysOfWeek like

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

And iterate over the range using Stream.iterate and filter if DayOfWeek of LocalDate contains in your daysOfWeek then collect localdates in list

  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());
  }
Eklavya
  • 17,618
  • 4
  • 28
  • 57
2

You can do it as follows:

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;
    }
}

Output:

[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]

Note: If the day names in the parameter can be in any case, replace date.format(dtf).equals(day) with date.format(dtf).equalsIgnoreCase(day) in the code given above.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1
  1. Take your DaysOfWeek input string and parse it into a List<DayOfWeek> object. For example, by first calling .split("\\s*,\\s*") to obtain a string array containing Mon, Tue, etcetera.

  2. Turn the string "Mon" into DayOfWeek.MONDAY. See below.

  3. Create a for loop to loop through every date between start and end: for (LocalDate d = start; d.isBefore(end); d = d.plusDays(1)). Per date, fetch the day of week it represents, and check that it is in your list.

How do I turn "Mon" into DOW.MONDAY?

You can make your own hashmap that maps strings to DayOfWeek values. Alternatively, you can rely on java's date parsing, but it's a little tricky:

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

note how you'll have to specify language, of course. Across the planet there are quite a few ways to say 'monday', after all :)

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72