Lamma I/O

Basic Date Generation

Let's get started by generating a sequence of dates. All code used in this tutorial can be found here: Scala / Java

Notes: please always import import io.lamma._ if you are using Scala.


Generate a sequence of dates

Generate every single day from 2014-05-10 to 2014-05-12

Date(2014, 5, 10) to Date(2014, 5, 12)
Dates.from(new Date(2014, 5, 10)).to(new Date(2014, 5, 12)).build();

Result: every day generated into a sorted list. This can be used very much like Scala Range

List(2014-05-10, 2014-05-11, 2014-05-12)


Generate dates with a step

Generate every other day from 2014-05-10 to 2014-05-15

(2014, 5, 10) to (2014, 5, 15) by 2
Dates.from(2014, 5, 10).to(2014, 5, 15).by(2).build()

Result: every other day is generated in the list. Here we used tuple notation (yyyy, mm, dd) and Lamma will do the implicit conversion to Date object automatically.

List(Date(2014,5,10), Date(2014,5,12), Date(2014,5,14))


Generate by negative step

Generate date from 2014-05-20 to 2014-05-15 step -2

"2014-05-20" to "2014-05-15" by -2
Dates.from("2014-05-20").to("2014-05-15").by(-2).build();

Result: every other day is generated in the list. Here we used ISO 8601 date representation yyyy-MM-dd and Lamma will do the implicit conversion to Date object automatically.

List(Date(2014,5,20), Date(2014,5,18), Date(2014,5,16))


The io.lamma.Date class

  • Date.to(that: Date) will produce a DateRange object extending Traversable[Date], which means all collection methods like foreach, map are available. Similar as scala.collection.Range, result dates are generated lazily.
  • io.lamma.Date object, tuple form (Int, Int, Int) or ISO form yyyy-MM-dd can be used interchangeably. As long as import io.lamma._ is in the Scala file, all conversion will be handled by Lamma.
  • io.lamma.Date is immutable and thus thread-safe. Any mutating operations (eg, + / -) will return a new copy.

Generate dates by week

Generate a date sequence from 2014-05-10 to 2014-05-24 by week

(2014, 5, 10) to (2014, 5, 24) by week
Dates.from(2014, 5, 10).to(2014, 5, 24).byWeek().build();

Result: every following date generated as 7 days (one week) from the previous date

List(2014-05-10, 2014-05-17, 2014-05-24)


Similarly, generate dates by month

Generate dates recurring every month from 2014-05-10 to 2014-07-10

(2014, 5, 10) to (2014, 7, 10) by month
Dates.from(2014, 5, 10).to(2014, 7, 10).byMonth().build();

Result: a sequence starting from 2014-05-10 and recurring at the 10th day of each subsequent months

List(2014-05-10, 2014-06-10, 2014-07-10)


Month end is handled properly

Generate dates recurring every month from 2014-01-31 to 2014-04-30

(2014, 1, 31) to (2014, 4, 30) by month
Dates.from(2014, 1, 31).to(2014, 4, 30).byMonth().build();

Result: month end handled properly even with different ending days of each month

List(2014-01-31, 2014-02-28, 2014-03-31, 2014-04-30)


and recurring by year

Generate dates recurring every year from 2014-05-10 to 2016-05-10

(2014, 5, 10) to (2016, 5, 10) by year
Dates.from(2014, 5, 10).to(2016, 5, 10).byYear().build();

Result: a sequence starting from 2014-05-10 and recurring on May 10th of each subsequent year

List(2014-05-10, 2015-05-10, 2016-05-10)


Leap year is handled properly

Generate dates recurring every year from 2012-02-29 to 2016-02-29

(2012, 2, 29) to (2016, 2, 29) by year
Dates.from(2012, 2, 29).to(2016, 2, 29).byYear().build();

Result: when starting the sequence on leap day of Feb 29th, all subsequent recurring dates in common years automatically adjusted to Feb 28th

List(2012-02-29, 2013-02-28, 2014-02-28, 2015-02-28, 2016-02-29)


Generate dates by multiple days

Generate sequence recurring every 3 days from 2014-05-10 to 2014-05-19

(2014, 5, 10) to (2014, 5, 19) by (3 days)   // add () to prevent confusing compiler
// we can `omit` days here: (2014, 5, 10) to (2014, 5, 19) by 3
Dates.from(2014, 5, 10).to(2014, 5, 19).byDays(3).build();

Result: a sequence starting from 2014-05-10 and recurring every 3 days

List(2014-05-10, 2014-05-13, 2014-05-16, 2014-05-19)


And by multiple weeks, months or years

Generate sequence recurring every 3 months from 2014-05-10 to 2014-11-10

(2014, 5, 10) to (2014, 11, 10) by (3 months)  // remember the () for 3 months
Dates.from(2014, 5, 10).to(2014, 11, 10).byMonths(3).build();

Result: a sequence starting from 2014-05-10 and recurring every 3 months

List(2014-05-10, 2014-08-10, 2014-11-10)


Recurring each leap year

Generate all leap days from 2012 to 2020

(2012, 2, 29) to (2020, 2, 29) by (4 years)  // again, add () for 4 years
Dates.from(2012, 2, 29).to(2020, 2, 29).byYears(4).build();

Result: leap days from 2012 to 2020

List(2012-02-29, 2016-02-29, 2020-02-29)


Filter out weekends from the result

Generate all non-weekend dates from 2015-10-08 to 2015-10-12

(2015, 10, 8) to (2015, 10, 12) except Weekends
Dates.from(2015, 10, 8).to(2015, 10, 12).except(HolidayRules.weekends()).build();

Result: dates are first generated and then all weekends are excluded

List(2015-10-08, 2015-10-09, 2015-10-12)


Filter out weekends as well as holidays

Generate all dates from 2015-12-23 to 2015-12-30 except weekends and holiday

val UKHoliday2015 = SimpleHolidayRule(
      Date(2015, 1, 1),
      Date(2015, 4, 3),
      Date(2015, 4, 6),
      Date(2015, 5, 4),
      Date(2015, 5, 25),
      Date(2015, 8, 31),
      Date(2015, 12, 25),
      Date(2015, 12, 28)
    )

// these two styles are identical

// Style 1
(2015, 12, 23) to (2015, 12, 30) except Weekends except UKHoliday2015

// Style 2
(2015, 12, 23) to (2015, 12, 30) except (Weekends and UKHoliday2015)
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

// Style 1
Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends()).except(ukHoliday2015).build();

// Style 2
Dates.from(2015, 12, 23).to(2015, 12, 30).except(HolidayRules.weekends().and(ukHoliday2015)).build();

Result: dates are first generated and then all weekends and holidays are excluded

List(Date(2015,12,23), Date(2015,12,24), Date(2015,12,29), Date(2015,12,30))