use super::funejson::Value; use super::dates_add_days::epoch_day_from_iso; /// Days two ranges have in common. `end_inclusive` says whether each end date /// is the range's last day (a statement period) or the day after it (a /// half-open range, a hotel stay); both ranges use the same convention. /// /// # Panics /// Panics on a malformed date or a range that ends before it starts. pub fn overlap_days(a_start: &str, a_end: &str, b_start: &str, b_end: &str, end_inclusive: bool) -> i64 { let a0 = epoch_day_from_iso(a_start); let a1 = epoch_day_from_iso(a_end); let b0 = epoch_day_from_iso(b_start); let b1 = epoch_day_from_iso(b_end); if a1 < a0 { panic!("range A starts {}, after its end {}", a_start, a_end); } if b1 < b0 { panic!("range B starts {}, after its end {}", b_start, b_end); } // An inclusive end is the half-open end one day later. let extra = if end_inclusive { 1 } else { 0 }; let days = a1.min(b1) + extra - a0.max(b0); days.max(0) } pub fn fune_vector(args: &[Value]) -> Value { Value::Int(overlap_days( args[0].as_str(), args[1].as_str(), args[2].as_str(), args[3].as_str(), args[4].as_bool(), )) }