Lamma I/O

Lamma Date

Your ultimate date generation solution for Java / Scala

Basic date manipulation

Date(2014, 7, 2) + 3  // result: Date(2014, 7, 5)

Date(2014, 7, 8) - Date(2014, 7, 2)  // result: 6

Date(2014, 7, 8) > Date(2014, 7, 2) // result: true
new Date(2014, 7, 2).plusDays(3);  // result: Date(2014, 7, 5)

new Date(2014, 7, 8).minus(new Date(2014, 7, 2));  // result: 6

new Date(2014, 7, 8).isAfter(new Date(2014, 7, 2)); // result: true

Advanced dates generation

Generate list of dates from 2014-12-01 to 2014-12-31 by every 5 days except weekends.

Date(2014, 12, 1) to Date(2014, 12, 31) by 5 except Weekends
Dates.from(2014, 11, 1).to(2014, 12, 31).byDays(10).except(HolidayRules.weekends()).build();

Result:

// Date(2014,12,6) and Date(2014,12,21) are not in the list because they are weekends.
List(Date(2014,12,1), Date(2014,12,11), Date(2014,12,16), Date(2014,12,26), Date(2014,12,31))

Professional schedule generation

Generate coupon schedule for following FCN (fixed coupon note):

  • Tenor: 37 months
  • Issue Date: 2014-03-01
  • Expiry Date: 2017-03-31 // merge last stub period
  • Frequency: every 6 months (semi-annual)
  • Coupon Date: Last day of month, modified following (last working day of the month)
  • Settlement Date: Coupon Date + 2 working days
Got it!
// a real business calendar will be used in production
val cal = Weekends
// coupon date = end date of each generated period, modified following convention
val couponDate = DateDef("CouponDate", relativeTo = PeriodEnd, selector = ModifiedFollowing(cal))
// settlement date = coupon date + 2 working days with the same calendar
val settlementDate = DateDef("SettlementDate", relativeTo = OtherDate("CouponDate"), shifter = ShiftWorkingDays(2, cal))

Schedule(start = Date(2014, 3, 1),   // issue date = 2014-03-01
         end = Date(2017, 3, 31),    // expiry date = 2017-03-31
         pattern = Months(6, LastDayOfMonth),    // recurring the last day of every 6 months
         periodBuilder = StubRulePeriodBuilder(endRule = LongEnd(270)),  // merge last stub if the merged period is no longer than 270 days
         dateDefs = couponDate :: settlementDate :: Nil    // generate coupon date and settlement date for each period
)
// a real business holiday rule will be used in production
HolidayRule cal = HolidayRules.weekends();
// coupon date = end date of each generated period, modified following convention
DateDef couponDate = DateDefs.of("CouponDate", Anchors.periodEnd(), Selectors.modifiedFollowing(cal));
// settlement date = coupon date + 2 working days with the same calendar
DateDef settlementDate = DateDefs.of("SettlementDate", Anchors.otherDate("CouponDate"), Shifters.byWorkingDays(2, cal));

Schedule4j result = Schedule4j.schedule(
    Dates.newDate(2014, 3, 1),              // issue date = 2014-03-01
    Dates.newDate(2017, 3, 31),             // expiry date = 2017-03-31
    Patterns.monthly(6, DayOfMonths.lastDay()),// recurring the last day of every 6 months
    StubRulePeriodBuilders.of(StubRulePeriodBuilders.Rules.longEnd(270)),    // merge last stub if the merged period is no longer than 270 days
    Lists.newArrayList(couponDate, settlementDate));      // generate coupon date and settlement date for each period
Generated Schedule
Period From Date To Date CouponDate SettlementDate
1 2014-03-01 2014-08-31 12014-08-29 42014-09-02
2 2014-09-01 2015-02-28 12015-02-27 42015-03-03
3 2015-03-01 2015-08-31 2015-08-31 2015-09-02
4 2015-09-01 22016-02-29 22016-02-29 2016-03-02
5 2016-03-01 2016-08-31 2016-08-31 2016-09-02
6 2016-09-01 32017-03-31 2017-03-31 42017-04-04

What do you get?

  1. Modified Following convention is applied based on holiday calendar.
  2. Leap year is handled properly.
  3. End stub month (2017-03) is merged automatically to the last period.
  4. Non-working days are skipped when calculating settlement date from coupon date.

Want to give it a try?

Visit our quick start page.

All code used in this page can be found here: Scala / Java