Skip to content

Instantly share code, notes, and snippets.

@fcroiseaux
Created December 4, 2012 05:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fcroiseaux/4201067 to your computer and use it in GitHub Desktop.
Save fcroiseaux/4201067 to your computer and use it in GitHub Desktop.
Utils class to calculate and work with holidays in a country (here in Luxembourg)
package utils
import org.joda.time.{Period, LocalDate}
object DateUtils {
def dateRange(from: LocalDate, to: LocalDate, step: Period): Iterator[LocalDate] =
Iterator.iterate(from) {
dt => dt.plus(step)
}.takeWhile(!_.isAfter(to))
def workDayRange(year: Int)(from: LocalDate, to: LocalDate): Iterator[LocalDate] =
Iterator.iterate(from) {
nextWorkDay(year)(_)
}.takeWhile(!_.isAfter(to))
def nextWorkDay(year: Int)(date: LocalDate): LocalDate = {
val next = date.plusDays(1)
if (isWorkDay(year)(next))
next
else
nextWorkDay(year)(next)
}
def isWorkDay(year: Int)(date: LocalDate): Boolean = {
date.getDayOfWeek != 6 &&
date.getDayOfWeek != 7 &&
!holidays(year).contains(date)
}
def fixedHolidays(year: Int) = Set(
new LocalDate(year, 12, 25),
new LocalDate(year, 12, 26),
new LocalDate(year, 1, 1),
new LocalDate(year, 6, 23),
new LocalDate(year, 8, 15),
new LocalDate(year, 5, 1),
new LocalDate(year, 11, 1))
def mobileHolidays(year: Int) = {
val easterSunday = easter(year)
val easterMonday = easterSunday.plusDays(1)
val ascension = easterSunday.plusDays(39)
val pentecote = easterSunday.plusDays(50)
Set(easterMonday, ascension, pentecote)
}
def holidays(year: Int) = fixedHolidays(year) ++ mobileHolidays(year)
def sortedHolidays(year: Int) = holidays(year).toList.sortWith((d1,d2) => d1.isBefore(d2))
def easter(year: Int) = {
val g = year % 19
val c = Math.floor(year / 100)
val c_4 = Math.floor(c / 4)
val h = (19 * g + c - c_4 - Math.floor((8 * c + 13) / 25) + 15) % 30
val k = Math.floor(h / 28)
val i = (k * Math.floor(29 / (h + 1)) * Math.floor((21 - g) / 11) - 1) * k + h
val weekDay = (Math.floor(year / 4) + year + i + 2 + c_4 - c) % 7
val presDay = (28 + i - weekDay).toInt
val month = if (presDay > 31) 3 else 2
val dayInMonth = if (month == 2) presDay else presDay - 31
new LocalDate(year, month + 1, dayInMonth)
}
}
@FloWi
Copy link

FloWi commented Nov 1, 2014

Great, thanks for sharing!

We'll modify your code and post a solution for the German holidays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment