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