Click here to Skip to main content
Click here to Skip to main content

Java date generation with Lamma date library (2)

, 10 Aug 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
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

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:

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(); 
// 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:

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:

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

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

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

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:

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:

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:

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)

Share

About the Author

maxcellent

United States United States
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 10 Aug 2014
Article Copyright 2014 by maxcellent
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid