///|
pub fn DateRange::contains(self : DateRange, date : Date) -> Bool {
self.start <= date && date <= self.end
}
///|
pub fn DateRange::overlaps(self : DateRange, other : DateRange) -> Bool {
self.start <= other.end && other.start <= self.end
}
///|
pub fn DateRange::intersection(
self : DateRange,
other : DateRange,
) -> Result[DateRange, DateRangeError] {
if !self.overlaps(other) {
Err(NoIntersection)
} else {
let start = if self.start >= other.start { self.start } else { other.start }
let end = if self.end <= other.end { self.end } else { other.end }
Ok({ start, end })
}
}
///|
pub fn DateRange::union(
self : DateRange,
other : DateRange,
) -> Result[DateRange, DateRangeError] {
let (left, right) = if self.start <= other.start {
(self, other)
} else {
(other, self)
}
let left_end = days_from_civil(left.end.year, left.end.month, left.end.day)
let right_start = days_from_civil(
right.start.year,
right.start.month,
right.start.day,
)
if right_start - left_end > 1 {
Err(NoIntersection)
} else {
let end = if left.end >= right.end { left.end } else { right.end }
Ok({ start: left.start, end })
}
}
///|
pub fn DateRange::calendar_days(self : DateRange) -> Int {
days_from_civil(self.end.year, self.end.month, self.end.day) -
days_from_civil(self.start.year, self.start.month, self.start.day) +
1
}
///|
pub fn DateRange::business_days(self : DateRange, calendar : Calendar) -> Int {
let mut current = self.start
let mut count = 0
while current != self.end {
if calendar.is_business_day(current) {
count = count + 1
}
current = match current.try_add_days(1) {
Ok(next) => next
Err(_) => panic()
}
}
if calendar.is_business_day(current) {
count = count + 1
}
count
}