Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Java date generation with Lamma date library (2)

0.00/5 (No votes)
10 Aug 2014CPOL1 min read 9.4K   38  
This article discusses basic date sequence generation with Lamma date library in Java

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

Java
Dates.from(new Date(2014, 5, 10)).to(new Date(2014, 5, 12)).build(); 
// result => [Date(2014,5,10), Date(2014,5,11), Date(2014,5,12)]

The result will have type List<Date>, which means it can be used in for-comprehension just like other Java List. 

For example:

Java
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:

Java
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:

Java
Dates.from(2014, 5, 10).to(2014, 5, 12).build(); 
// result => [Date(2014,5,10), Date(2014,5,11), Date(2014,5,12)]

Generate dates by different step

Generate every other day from 2014-05-10 to 2014-05-15 with by method:

Java
Dates.from(2014, 5, 10).to(2014, 5, 15).by(2).build(); 
// result => [Date(2014,5,10), Date(2014,5,12), Date(2014,5,14)]

Generate date from 2014-05-20 to 2014-05-15 by negative step -2:

Java
Dates.from("2014-05-20").to("2014-05-15").by(-2).build(); 
// result => [Date(2014,5,20), Date(2014,5,18), Date(2014,5,16)]

 

By week / weeks

Java
Dates.from(2014, 5, 10).to(2014, 5, 24).byWeek().build();    // by single week
// result => [Date(2014,5,10), Date(2014,5,17), Date(2014,5,24)]

Dates.from(2014, 5, 10).to(2014, 5, 24).byWeeks(2).build();  // by multiple weeks
// result => [Date(2014,5,10), Date(2014,5,24)]

By month / months

Java
Dates.from(2014, 5, 10).to(2014, 7, 10).byMonth().build();  // by single month
// result => [Date(2014,5,10), Date(2014,6,10), Date(2014,7,10)]

Dates.from(2014, 1, 31).to(2014, 4, 30).byMonth().build();  // month end is handled properly
// result => [Date(2014,1,31), Date(2014,2,28), Date(2014,3,31), Date(2014,4,30)]

Dates.from(2014, 5, 10).to(2014, 11, 10).byMonths(3).build();  // by multiple months
// result => [Date(2014,5,10), Date(2014,8,10), Date(2014,11,10)]

By year / years

Java
Dates.from(2014, 5, 10).to(2016, 5, 10).byYear().build(); // by single year
// result => [Date(2014,5,10), Date(2015,5,10), Date(2016,5,10)]

Dates.from(2012, 2, 29).to(2016, 2, 29).byYear().build(); // leap year is handled properly
// result => [Date(2012,2,29), Date(2013,2,28), Date(2014,2,28), Date(2015,2,28), Date(2016,2,29)]

Dates.from(2012, 2, 29).to(2016, 2, 29).byYears(2).build(); // by multiple years
// result => [Date(2012,2,29), Date(2014,2,28), Date(2016,2,29)]

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:

Java
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); 
// result => [Date(2014,10,10), Date(2014,10,13), Date(2014,10,14), Date(2014,10,15)]

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:

Java
Dates.from(2014, 10, 10).to(2014, 10, 15).except(HolidayRules.weekends()).build(); 
// result => [Date(2014,10,10), Date(2014,10,13), Date(2014,10,14), Date(2014,10,15)]

Here is a more complicated example, which takes both weekends and bank holidays into consideration:

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

// these two styles are identical

Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends()).except(ukHoliday2015).build(); 
// => [Date(2015,12,23), Date(2015,12,24), Date(2015,12,29), Date(2015,12,30)]

Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends().and(ukHoliday2015)).build(); 
// => [Date(2015,12,23), Date(2015,12,24), Date(2015,12,29), Date(2015,12,30)]

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"

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)