Created
December 4, 2012 05:48
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great, thanks for sharing!
We'll modify your code and post a solution for the German holidays.