namespace TaxBaik.Web.Components.Admin.Shared; public static class BusinessDayCalculator { private sealed record HolidayWindow(DateOnly Start, DateOnly End) { public IEnumerable Dates() { for (var date = Start; date <= End; date = date.AddDays(1)) { yield return date; } } } private static readonly HolidayWindow[] HolidayWindows = { new(new DateOnly(2026, 1, 1), new DateOnly(2026, 1, 1)), new(new DateOnly(2026, 2, 16), new DateOnly(2026, 2, 18)), new(new DateOnly(2026, 3, 1), new DateOnly(2026, 3, 2)), new(new DateOnly(2026, 5, 5), new DateOnly(2026, 5, 5)), new(new DateOnly(2026, 6, 6), new DateOnly(2026, 6, 6)), new(new DateOnly(2026, 8, 15), new DateOnly(2026, 8, 17)), new(new DateOnly(2026, 9, 24), new DateOnly(2026, 9, 26)), new(new DateOnly(2026, 10, 3), new DateOnly(2026, 10, 5)), new(new DateOnly(2026, 10, 9), new DateOnly(2026, 10, 9)), new(new DateOnly(2026, 12, 25), new DateOnly(2026, 12, 25)), new(new DateOnly(2027, 1, 1), new DateOnly(2027, 1, 1)), new(new DateOnly(2027, 2, 6), new DateOnly(2027, 2, 9)), new(new DateOnly(2027, 3, 1), new DateOnly(2027, 3, 2)), new(new DateOnly(2027, 5, 5), new DateOnly(2027, 5, 5)), new(new DateOnly(2027, 5, 13), new DateOnly(2027, 5, 13)), new(new DateOnly(2027, 6, 6), new DateOnly(2027, 6, 6)), new(new DateOnly(2027, 8, 15), new DateOnly(2027, 8, 16)), new(new DateOnly(2027, 9, 14), new DateOnly(2027, 9, 16)), new(new DateOnly(2027, 10, 3), new DateOnly(2027, 10, 4)), new(new DateOnly(2027, 10, 9), new DateOnly(2027, 10, 11)), new(new DateOnly(2027, 12, 25), new DateOnly(2027, 12, 26)) }; private static readonly HashSet HolidayDates = BuildHolidayDates(); public static DateOnly GetEffectiveDueDate(DateOnly dueDate) { var effectiveDate = dueDate; while (!IsBusinessDay(effectiveDate)) { effectiveDate = effectiveDate.AddDays(1); } return effectiveDate; } public static int GetDday(DateOnly dueDate, DateOnly? referenceDate = null) { var today = referenceDate ?? DateOnly.FromDateTime(DateTime.Today); var effectiveDueDate = GetEffectiveDueDate(dueDate); return effectiveDueDate.DayNumber - today.DayNumber; } public static bool IsBusinessDay(DateOnly date) => date.DayOfWeek is not DayOfWeek.Saturday and not DayOfWeek.Sunday && !HolidayDates.Contains(date); private static HashSet BuildHolidayDates() { var holidays = new HashSet(); foreach (var window in HolidayWindows) { foreach (var date in window.Dates()) { holidays.Add(date); } } return holidays; } }