/
ByMonthRule.java
91 lines (77 loc) · 2.94 KB
/
ByMonthRule.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package net.fortuna.ical4j.transform.recurrence;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateList;
import net.fortuna.ical4j.model.NumberList;
import net.fortuna.ical4j.model.Recur.Frequency;
import net.fortuna.ical4j.model.WeekDay;
import net.fortuna.ical4j.model.parameter.Value;
import net.fortuna.ical4j.util.Dates;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
/**
* Applies BYMONTH rules specified in this Recur instance to the specified date list. If no BYMONTH rules are
* specified the date list is returned unmodified.
*/
public class ByMonthRule extends AbstractDateExpansionRule {
private final NumberList monthList;
private final Frequency frequency;
public ByMonthRule(NumberList monthList, Frequency frequency) {
this(monthList, frequency, Optional.empty());
}
public ByMonthRule(NumberList monthList, Frequency frequency, Optional<WeekDay.Day> weekStartDay) {
super(weekStartDay);
this.monthList = monthList;
this.frequency = frequency;
}
@Override
public DateList transform(DateList dates) {
if (monthList.isEmpty()) {
return dates;
}
final DateList monthlyDates = Dates.getDateListInstance(dates);
for (final Date date : dates) {
if (frequency == Frequency.YEARLY) {
monthlyDates.addAll(new ExpansionFilter(monthlyDates.getType()).apply(date));
} else {
Optional<Date> limit = new LimitFilter().apply(date);
if (limit.isPresent()) {
monthlyDates.add(limit.get());
}
}
}
return monthlyDates;
}
private class LimitFilter implements Function<Date, Optional<Date>> {
@Override
public Optional<Date> apply(Date date) {
final Calendar cal = getCalendarInstance(date, true);
// Java months are zero-based..
if (monthList.contains(cal.get(Calendar.MONTH) + 1)) {
return Optional.of(date);
}
return Optional.empty();
}
}
private class ExpansionFilter implements Function<Date, List<Date>> {
private final Value type;
public ExpansionFilter(Value type) {
this.type = type;
}
@Override
public List<Date> apply(Date date) {
List<Date> retVal = new ArrayList<>();
final Calendar cal = getCalendarInstance(date, true);
// construct a list of possible months..
monthList.forEach(month -> {
// Java months are zero-based..
// cal.set(Calendar.MONTH, month - 1);
cal.roll(Calendar.MONTH, (month - 1) - cal.get(Calendar.MONTH));
retVal.add(Dates.getInstance(cal.getTime(), type));
});
return retVal;
}
}
}