Files
taxbaik/TaxBaik.Web/Components/Admin/Shared/BusinessDayCalculator.cs
T
kjh2064 e65f01b196
TaxBaik CI/CD / build-and-deploy (push) Successful in 4m14s
fix(admin): align holiday tests and loading flow
2026-07-02 11:02:20 +09:00

80 lines
2.9 KiB
C#

namespace TaxBaik.Web.Components.Admin.Shared;
public static class BusinessDayCalculator
{
private sealed record HolidayWindow(DateOnly Start, DateOnly End)
{
public IEnumerable<DateOnly> 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<DateOnly> 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<DateOnly> BuildHolidayDates()
{
var holidays = new HashSet<DateOnly>();
foreach (var window in HolidayWindows)
{
foreach (var date in window.Dates())
{
holidays.Add(date);
}
}
return holidays;
}
}