-2

I am trying to figure out find out list of calendar dates from two specific dates. But I am getting only within a same year not fix two dates.

What I have done:

    private ArrayList<Calendar> weekendList = null;
    public void findWeekendsList(long startDate, long endDate)
    {
        weekendList = new ArrayList();
        Calendar calendarStart = null;
        Calendar calendarEnd=null;

        calendarStart= Calendar.getInstance();
        calendarStart.setTimeInMillis(startDate);



        /*calendarEnd= Calendar.getInstance();
        calendarEnd.setTimeInMillis(endDate);
       */

        // The while loop ensures that you are only checking dates in the current year

       while(calendar.get(Calendar.YEAR) == Calendar.getInstance().get(Calendar.YEAR)){
            // The switch checks the day of the week for Saturdays and Sundays
            switch(calendar.get(Calendar.DAY_OF_WEEK)){
                case Calendar.SATURDAY:
                case Calendar.SUNDAY:

                    weekendList.add(calendar);
                    break;
            }

            // Increment the day of the year for the next iteration of the while loop
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }
    }

I am getting 102 weekends and it was like jan 9 to dec 31 but i want to today date(jan 9, 2018) to up to next year( like jan 9 2019), all the weekends in arrayList.

If anyone have any idea, that would great help for me.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
No_Name_Code
  • 299
  • 10
  • 20
  • Take the current `Date`, increment the year by `1`, this becomes the target end date - something like [this](https://stackoverflow.com/questions/16785643/get-the-list-of-dates-between-two-dates/16785762#16785762) - but I'd be using the newer Date/Time API – MadProgrammer Jan 09 '18 at 08:02
  • You `while` condition seems wrong, it should be more like `while (calendar.getTime().before(toDate)) {`, where `toDate` is after the last `Date` you want to check – MadProgrammer Jan 09 '18 at 08:04
  • Also, because `Calendar` is mutable, adding `calendar` will simply produce a list of values which all have the same date – MadProgrammer Jan 09 '18 at 08:08
  • Also, technically, because you adding both `Saturday` and `Sunday`, you're getting to days per "weekend" – MadProgrammer Jan 09 '18 at 08:11

1 Answers1

3

So, immediately, you have a number of issues which stand out...

  • Using an out of date API. Calendar should be avoided at all costs, it's troublesome, clumsy and all way to easy to screw up
  • The while loop is looping only so long as the year is the same, so it's ignoring the endDate altogether
  • Because Calendar is mutable, all you are producing is a List with the same date/time value contained within it
  • You algorithm considers a weekend to be both "Saturday" or "Sunday", where normally, I'd consider a weekend to be the time between "Friday" and "Monday" - Don't know if this is deliberate on your part, but it stands out to me.

Since Java 8 included a newer Date/Time API, you should start using it. If you're not using Java 8+ (and I'd be asking some serious questions as to why not), you should be using a more reliable API - JodaTime comes to mind, but there is also a compatible back port of the Java 8 Date/Time for earlier JDK/JVMs

Now, having said all that, I'd do something more like...

public List<LocalDate> findWeekendsBetween(long startTime, long endTime) {
    LocalDate startDate = LocalDate.ofEpochDay(startTime);
    LocalDate endDate = LocalDate.ofEpochDay(endTime);

    System.out.println("Starting from " + startDate);
    System.out.println("Ending at " + endDate);

    List<LocalDate> weekends = new ArrayList<>(25);
    while (startDate.isBefore(endDate) || startDate.equals(endDate)) {
        switch (startDate.getDayOfWeek()) {
            case SATURDAY:
                weekends.add(startDate);
                startDate = startDate.plusDays(2);
                break;
            default:
                startDate = startDate.plusDays(1);
        }
    }
    return weekends;
}

In fact, I'd even change it so that callers were required to pass you LocalDate values...

public List<LocalDate> findWeekendsBetween(LocalDate startDate, LocalDate endDate) {

as long is ambiguous.

The above algorithm is inclusive of the startTime and endTime and considers a "weekend" to be the time between "Friday" and "Monday", so it will only return "Saturday" values

Then you could call it using something like...

LocalDate startDate = LocalDate.now();
LocalDate endDate = startDate.plusMonths(1);

List<LocalDate> weekends = findWeekendsBetween(startDate.toEpochDay(), endDate.toEpochDay());
System.out.println("Found " + weekends.size() + " Saturday/Sundays");
for (LocalDate date : weekends) {
    System.out.println(date);
}

(as you can see, I'm to lazy to calculate a fixed point in time and just use LocalDate and convert it to a long value)

Which in my testing printed out something like...

Starting from 2018-01-09
Ending at 2018-02-09
Found 4 Weekends
2018-01-13
2018-01-20
2018-01-27
2018-02-03

but you have only added Saturday, it has to be Sundays also.

Yes, as I said, I made it accept only Saturday, as for me, a weekend is inclusive of Saturday AND Sunday.

It would be easily fixed by simply including SUNDAY into the switch statement...

switch (startDate.getDayOfWeek()) {
    case SATURDAY:
    case SUNDAY:
        weekends.add(startDate);
        break;
    default:
        startDate = startDate.plusDays(1);
}

I think, it might be 52*2=104 list size.

I've not tested a full year, I've only checked a month's worth. You could just change the end date, something like...

LocalDate endDate = startDate.plusYears(1);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thank you so much for your valuable answer, i really appreciate. – No_Name_Code Jan 09 '18 at 10:01
  • I really grateful for your answer, but you have only added Saturday, it has to be Sundays also. I think, it might be 52*2=104 list size. – No_Name_Code Jan 09 '18 at 10:21
  • For Java 6 and Java 7, much of the *java.time* functionality can be found in the *ThreeTen-Backport* project. For earlier Android, see the *ThreeTenABP* project. The *Joda-Time* project is now in maintenance mode, with its team advising migration to the *java.time* classes (or the back-port). – Basil Bourque Jan 09 '18 at 16:37
  • @No_Name_Code As I said, I was only capturing Saturday, how hard would it be for you to include Sunday, if that’s important to you. In my example, I’m only scanning one month, how hard do you think it would be for you to change to capture a year? – MadProgrammer Jan 09 '18 at 18:28
  • @BasilBourque I did mention it, maybe not by name – MadProgrammer Jan 09 '18 at 18:29
  • I am using below api 26, so it can not support to below 26, however it was find in oreo but in naught, marshmallow , there should be error, Can we do that without using LocalDate. – No_Name_Code Jan 10 '18 at 17:55
  • @No_Name_Code You didn't specify that you were using Android, it kind makes a difference. I'd recommend looking at the ThreeTen Backport (now linked in the answer) – MadProgrammer Jan 10 '18 at 18:57
  • @No_Name_Code Regarding Android, read my comment, third above your own. – Basil Bourque Jan 11 '18 at 21:53