2

For Example I have the date range: "1/6/2020 - 7/6/2020" and it have 5 days of Weekdays (1/6 - 5/6) and 2 days of Weekend (6/6 - 7/6). I want to pass it to a function which would return 2 separate date list, weekdays and weekend. How can I do this? I tried the code below, it is working, but i cannot use it outside the "while" function as the return results can only be used in the "while" loop.

SimpleDateFormat dfs= new SimpleDateFormat("yyyy-MM-dd");
Date sd = dformat.parse(param_start);
Date ed = dformat.parse(param_end);
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(sd);
c2.setTime(ed);
String pstart = "";

while(!c1.after(c2)){
    System.out.println("WD Date: " + dfs.format(c1.getTime()));
    pstart = "'"+dfs.format(c1.getTime())+" 00:00:00',";
    out.print(pstart.substring(0,pstart.length()-1));
    int dayOfWeek = c1.get(Calendar.DAY_OF_WEEK);
      if (dayOfWeek == Calendar.FRIDAY) {
          c1.add(Calendar.DATE, 3);
      } else if (dayOfWeek == Calendar.SATURDAY) {
           c1.add(Calendar.DATE, 2);
      } else {
           c1.add(Calendar.DATE, 1);
      }
}

Appreciate any help i could get. Thanks

justarandomguy
  • 145
  • 1
  • 13
  • 1
    Why `java.util`? Are you somehow forced to use a lower Java version? Otherwise, use `java.time`... – deHaar Jun 05 '20 at 10:06
  • 1
    Is it what to return that confuses you? I'd suggest something like `Map>` with two keys "weekdays" and "weekend" whose values you'd populate during your iteration. – Aaron Jun 05 '20 at 10:09
  • @deHaar i am using it for Tomcat8.5, with Java 8.. not sure about it whether can use newer libraries :( i am really new to Java – justarandomguy Jun 05 '20 at 11:05
  • 1
    Then read the answers given by @ArvindKumarAvinash and me ;-) You should really go with the best datetime API available. It was introduced in Java 8... – deHaar Jun 05 '20 at 11:06
  • 1
    @deHaar will do, thanks for the help, really appreciate it so much. :) – justarandomguy Jun 05 '20 at 11:08

3 Answers3

2

Instead of using the outdated java.util.Date and SimpleDateFormat, you should use java.time.LocalDate and DateTimeFormatter. Check this to learn more about the modern date/time API.

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // Test
        Map<String, List<LocalDate>> map = getWeekdaysAndWeekends("1/6/2020", "7/6/2020");
        List<LocalDate> weekdays = map.get("weekdays");
        List<LocalDate> weekends = map.get("weekends");

        System.out.println("Weekdays:");
        weekdays.forEach(System.out::println);

        System.out.println("Weekends:");
        weekends.forEach(System.out::println);
    }

    static Map<String, List<LocalDate>> getWeekdaysAndWeekends(String strStartDate, String strEndDate) {
        Map<String, List<LocalDate>> map = new HashMap<>();
        List<LocalDate> weekdays = new ArrayList<>();
        List<LocalDate> weekends = new ArrayList<>();
        map.put("weekdays", weekdays);
        map.put("weekends", weekends);

        // Define format
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy");

        // Parse the string dates into LocalDate
        LocalDate startDate = LocalDate.parse(strStartDate, formatter);
        LocalDate enddDate = LocalDate.parse(strEndDate, formatter);

        for (LocalDate date = startDate; !date.isAfter(enddDate); date = date.plusDays(1)) {
            switch (date.getDayOfWeek()) {
            // Add Mon to Fri to weekdays
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
            case FRIDAY:
                weekdays.add(date);
                break;

            // Add Sat and Sun to weekends
            case SATURDAY:
            case SUNDAY:
                weekends.add(date);
            }
        }
        return map;
    }
}

Output:

Weekdays:
2020-06-01
2020-06-02
2020-06-03
2020-06-04
2020-06-05
Weekends:
2020-06-06
2020-06-07
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • I am getting `Method references are allowed only at source level 1.8 or above` error message – justarandomguy Jun 07 '20 at 10:58
  • @justarandom - This code requires Java 8. From your comment, I understood that you are using [Tomcat 8.5](https://stackoverflow.com/questions/18208805/does-tomcat-8-support-java-8) which supports Java 8. You will need [ThreeTen-Backport](https://www.threeten.org/threetenbp/index.html) in order to use this code with Java 7. Feel free to let me know if you want me to provide code for Java 7 without using ThreeTen-Backport. – Arvind Kumar Avinash Jun 07 '20 at 11:52
1

You can use Map<String,List<Date>> to hold weekDays and Weekend Or you can create a class with two attribute of type List<Date>

Below Funtion will give you week Days and weekend separatly.

public  Map<String,List<Date>> datePartionar(String startDate,String endDate) {
    // Define map and initialize
    Map<String,List<Date>> res = new HashMap<>();
    res.put("weekend",new ArrayList<>());
    res.put("weekDays",new ArrayList<>());
    try {
        // parse date and initialize calender Date
        SimpleDateFormat dfs= new SimpleDateFormat("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(dfs.parse(startDate));
        c2.setTime(dfs.parse(endDate));
        String pstart = "";

        while(!c1.after(c2)){
            int dayOfWeek = c1.get(Calendar.DAY_OF_WEEK);
            if(dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY){
                res.get("weekend").add(c1.getTime());
            }
            else {
                res.get("weekDays").add(c1.getTime());
            }
            c1.add(Calendar.DATE, 1);
        }
    }
    catch (ParseException pe){
        pe.printStackTrace();
        return  null;
    }

    return res;
}
rohit prakash
  • 565
  • 6
  • 12
1

One possible solution (using java.time) could consist of two methods, each taking two LocalDates that represent the beginning of the range and the end of the range. Each method returns a List<LocalDate>, see this:

Get the weekend days with this method

public static List<LocalDate> getWeekendDaysIn(LocalDate first, LocalDate last) {
    List<LocalDate> weekendDays = new ArrayList<>();
    LocalDate localDate = first;

    while (!localDate.equals(last)) {
        localDate = localDate.plusDays(1);

        switch (localDate.getDayOfWeek()) {
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
            case FRIDAY:
                break;
            case SATURDAY:
            case SUNDAY:
                weekendDays.add(localDate);
                break;
            default:
                break;
        }
    }

    return weekendDays;
}

and the working days with the following method

public static List<LocalDate> getWorkingDaysIn(LocalDate first, LocalDate last) {
    List<LocalDate> workingDays = new ArrayList<>();
    LocalDate localDate = first;

    while (!localDate.equals(last)) {
        localDate = localDate.plusDays(1);

        switch (localDate.getDayOfWeek()) {
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
            case FRIDAY:
                workingDays.add(localDate);
                break;
            case SATURDAY:
            case SUNDAY:
                break;
            default:
                break;
        }
    }

    return workingDays;
}

Then use it in an example main like this

public static void main(String[] args) throws SQLException {
    LocalDate from = LocalDate.now();
    LocalDate to = from.plusDays(10);

    List<LocalDate> workingDays = getWorkingDaysIn(from, to);
    List<LocalDate> weekendDays = getWeekendDaysIn(from, to);

    System.out.printf("Range: %s to %s", from, to);
    System.out.println();
    System.out.println("Weekdays: ");
    workingDays.forEach(System.out::println);
    System.out.println();
    System.out.println("Weekends");
    weekendDays.forEach(System.out::println);
}

and receive the output

Range: 2020-06-05 to 2020-06-15
Weekdays: 
2020-06-08
2020-06-09
2020-06-10
2020-06-11
2020-06-12
2020-06-15

Weekends
2020-06-06
2020-06-07
2020-06-13
2020-06-14

when the day of execution is 5th of June 2020.

deHaar
  • 17,687
  • 10
  • 38
  • 51