As Konrad Morawski already pointed out, working days are culture related. I've worked out a working day calculator that is extendible so every culture can be supported.
The extension method WorkingDay
uses a static class OffDayProvider
to determine whether a given day is an day off. By default this OffDayProvider
does not consider any day to be an off day. By injecting one or more IOffDayProvider
s you can determine what days are off days.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var startDate = new DateTime(2015,12,1);
var date = new DateTime(2015,12,31);
Console.WriteLine("{0} -- {1}",date.ToShortDateString(), date.WorkingDay(startDate));
OffDayProvider.Providers.Add(new WeekendProvider());
OffDayProvider.Providers.Add(new BankHolidayProvider());
OffDayProvider.Providers.Add(new WinterSolsticeProvider());
Console.WriteLine("{0} -- {1}",date.ToShortDateString(), date.WorkingDay(startDate));
}
}
public static class DateTimeExtensions
{
public static int WorkingDay(this DateTime date, DateTime startDate)
{
var result = 0;
for(var day = startDate; day <= date; day = day.AddDays(1))
{
if(OffDayProvider.IsOffDay(day))
{
continue;
}
result++;
}
return result;
}
public static int WorkingDay(this DateTime date)
{
return date.WorkingDay(new DateTime(date.Year, 1, 1));
}
}
public static class OffDayProvider
{
public static readonly ICollection<IOffDayProvider> Providers = new List<IOffDayProvider>();
public static bool IsOffDay(DateTime date)
{
return Providers.Any(x => x.IsOffDay(date));
}
}
public interface IOffDayProvider
{
bool IsOffDay(DateTime date);
}
public class WeekendProvider : IOffDayProvider
{
public bool IsWeekend(DateTime date)
{
return date.DayOfWeek == DayOfWeek.Sunday
|| date.DayOfWeek == DayOfWeek.Saturday;
}
public bool IsOffDay(DateTime date)
{
return IsWeekend(date);
}
}
public class WinterSolsticeProvider : IOffDayProvider
{
public bool IsWinterSolstice(DateTime date)
{
return date.Month == 12 && date.Day == 21;
}
public bool IsOffDay(DateTime date)
{
return IsWinterSolstice(date);
}
}
public class BankHolidayProvider : IOffDayProvider
{
public bool IsChristmasDay(DateTime date)
{
return date.Month == 12 && date.Day == 25;
}
public bool IsBoxingDay(DateTime date)
{
return date.Month == 12 && date.Day == 26;
}
public bool IsOffDay(DateTime date)
{
return IsChristmasDay(date)
|| IsBoxingDay(date);
}
}
I did not include checks for corner cases. It's up to you to determine how to handle those.
I did not include any comments either. Well written code doesn't need comments, does it? B-)