Introduction
In previous article we discussed basic date manupilations with Lamma date library, this article discusses a more complicated use case: generate a sequence of date. For example, how to generate all dates in December 2014 except weekends?
Using the code
Generate a sequence of dates
Generate every single day from 2014-05-10 to 2014-05-12
Dates.from(new Date(2014, 5, 10)).to(new Date(2014, 5, 12)).build();
The result will have type List<Date>
, which means it can be used in for-comprehension just like other Java List.
For example:
List<Date> dates = Dates.from(new Date(2014, 5, 10)).to(new Date(2014, 5, 12)).build();
for (Date date: dates) {
System.out.println(date);
}
will print out all dates from 2014-05-10
to 2014-05-12
:
Date(2014,5,10)
Date(2014,5,11)
Date(2014,5,12)
from
and to
methods also take (Int, Int, Int)
as parameters, which saves typing new Date(yyyy, MM, dd)
constructor every time. For example:
Dates.from(2014, 5, 10).to(2014, 5, 12).build();
Generate dates by different step
Generate every other day from 2014-05-10 to 2014-05-15 with by
method:
Dates.from(2014, 5, 10).to(2014, 5, 15).by(2).build();
Generate date from 2014-05-20 to 2014-05-15 by negative step -2:
Dates.from("2014-05-20").to("2014-05-15").by(-2).build();
By week / weeks
Dates.from(2014, 5, 10).to(2014, 5, 24).byWeek().build();
Dates.from(2014, 5, 10).to(2014, 5, 24).byWeeks(2).build();
By month / months
Dates.from(2014, 5, 10).to(2014, 7, 10).byMonth().build();
Dates.from(2014, 1, 31).to(2014, 4, 30).byMonth().build();
Dates.from(2014, 5, 10).to(2014, 11, 10).byMonths(3).build();
By year / years
Dates.from(2014, 5, 10).to(2016, 5, 10).byYear().build();
Dates.from(2012, 2, 29).to(2016, 2, 29).byYear().build();
Dates.from(2012, 2, 29).to(2016, 2, 29).byYears(2).build();
Take weekends and holidays into consideration
In many cases we want to further filter the generated dates to exclude weekends or holidays.
This can be done with any existing collection filtering techniques. For example, following code will filter all non-weekends with Google Guava Library:
List<Date> result = Dates.from(2014, 10, 10).to(2014, 10, 15).build();
Predicate<Date> weekdays = new Predicate<Date>() {
@Override
public boolean apply(Date d) {
return ! d.is(DayOfWeek.SATURDAY) && ! d.is(DayOfWeek.SUNDAY) ;
}
};
Iterables.filter(result, weekdays);
Because this is a too common use case, Lamma introduced a new concept called HolidayRule
, which provides an interface to define holidays, there are quite a few helper methods in HolidayRules
class to construct holiday rules. With except(HolidayRule)
method and build-in HolidayRules.weekends()
rule, above code snippet can be replaced by following one liner:
Dates.from(2014, 10, 10).to(2014, 10, 15).except(HolidayRules.weekends()).build();
Here is a more complicated example, which takes both weekends and bank holidays into consideration:
HolidayRule ukHoliday2015 = HolidayRules.simpleRule(
new Date(2015, 1, 1), new Date(2015, 4, 3), new Date(2015, 4, 6),
new Date(2015, 5, 4), new Date(2015, 5, 25), new Date(2015, 8, 31),
new Date(2015, 12, 25), new Date(2015, 12, 28)
);
Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends()).except(ukHoliday2015).build();
Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends().and(ukHoliday2015)).build();
How to run sample code
The sample project requires maven to run. Once you have maven installed, go to lamma-java-2/ (the one with pom.xml) and execute following command:
mvn compile exec:java -Dexec.mainClass="io.lammasample2.Sample"