para laborables habiles fechas entre dias calcular algoritmo c# datetime

c# - laborables - Calcule el número de días hábiles entre dos fechas?



calcular dias habiles entre dos fechas javascript (25)

En C #, ¿cómo puedo calcular el número de días hábiles (o días de la semana) entre dos fechas?


Aquí hay un código de muestra rápido. Es un método de clase, por lo que solo funcionará dentro de tu clase. Si desea que sea static , cambie la firma a private static (o public static ).

private IEnumerable<DateTime> GetWorkingDays(DateTime sd, DateTime ed) { for (var d = sd; d <= ed; d.AddDays(1)) if (d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday) yield return d; }

Este método crea una variable de bucle d , la inicializa al día de inicio, sd , luego aumenta en un día cada iteración ( d.AddDays(1) ).

Devuelve los valores deseados usando yield , que crea un iterator . Lo bueno de los iteradores es que no tienen todos los valores de IEnumerable en la memoria, solo que los llama secuencialmente. Esto significa que puede llamar a este método desde el principio hasta ahora sin tener que preocuparse por quedarse sin memoria.


Aquí hay un código para ese propósito, con vacaciones en sueco, pero puede adaptar qué vacaciones contar. Tenga en cuenta que agregué un límite que tal vez quiera eliminar, pero fue para un sistema basado en la web y no quería que nadie ingresara una gran fecha para encerrar el proceso.

public static int GetWorkdays(DateTime from ,DateTime to) { int limit = 9999; int counter = 0; DateTime current = from; int result = 0; if (from > to) { DateTime temp = from; from = to; to = temp; } if (from >= to) { return 0; } while (current <= to && counter < limit) { if (IsSwedishWorkday(current)) { result++; } current = current.AddDays(1); counter++; } return result; } public static bool IsSwedishWorkday(DateTime date) { return (!IsSwedishHoliday(date) && date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday); } public static bool IsSwedishHoliday(DateTime date) { return ( IsSameDay(GetEpiphanyDay(date.Year), date) || IsSameDay(GetMayDay(date.Year), date) || IsSameDay(GetSwedishNationalDay(date.Year), date) || IsSameDay(GetChristmasDay(date.Year), date) || IsSameDay(GetBoxingDay(date.Year), date) || IsSameDay(GetGoodFriday(date.Year), date) || IsSameDay(GetAscensionDay(date.Year), date) || IsSameDay(GetAllSaintsDay(date.Year), date) || IsSameDay(GetMidsummersDay(date.Year), date) || IsSameDay(GetPentecostDay(date.Year), date) || IsSameDay(GetEasterMonday(date.Year), date) || IsSameDay(GetNewYearsDay(date.Year), date) || IsSameDay(GetEasterDay(date.Year), date) ); } // Trettondagen public static DateTime GetEpiphanyDay(int year) { return new DateTime(year, 1, 6); } // Första maj public static DateTime GetMayDay(int year) { return new DateTime(year,5,1); } // Juldagen public static DateTime GetSwedishNationalDay(int year) { return new DateTime(year, 6, 6); } // Juldagen public static DateTime GetNewYearsDay(int year) { return new DateTime(year,1,1); } // Juldagen public static DateTime GetChristmasDay(int year) { return new DateTime(year,12,25); } // Annandag jul public static DateTime GetBoxingDay(int year) { return new DateTime(year, 12, 26); } // Långfredagen public static DateTime GetGoodFriday(int year) { return GetEasterDay(year).AddDays(-3); } // Kristi himmelsfärdsdag public static DateTime GetAscensionDay(int year) { return GetEasterDay(year).AddDays(5*7+4); } // Midsommar public static DateTime GetAllSaintsDay(int year) { DateTime result = new DateTime(year,10,31); while (result.DayOfWeek != DayOfWeek.Saturday) { result = result.AddDays(1); } return result; } // Midsommar public static DateTime GetMidsummersDay(int year) { DateTime result = new DateTime(year, 6, 20); while (result.DayOfWeek != DayOfWeek.Saturday) { result = result.AddDays(1); } return result; } // Pingstdagen public static DateTime GetPentecostDay(int year) { return GetEasterDay(year).AddDays(7 * 7); } // Annandag påsk public static DateTime GetEasterMonday(int year) { return GetEasterDay(year).AddDays(1); } public static DateTime GetEasterDay(int y) { double c; double n; double k; double i; double j; double l; double m; double d; c = System.Math.Floor(y / 100.0); n = y - 19 * System.Math.Floor(y / 19.0); k = System.Math.Floor((c - 17) / 25.0); i = c - System.Math.Floor(c / 4) - System.Math.Floor((c - k) / 3) + 19 * n + 15; i = i - 30 * System.Math.Floor(i / 30); i = i - System.Math.Floor(i / 28) * (1 - System.Math.Floor(i / 28) * System.Math.Floor(29 / (i + 1)) * System.Math.Floor((21 - n) / 11)); j = y + System.Math.Floor(y / 4.0) + i + 2 - c + System.Math.Floor(c / 4); j = j - 7 * System.Math.Floor(j / 7); l = i - j; m = 3 + System.Math.Floor((l + 40) / 44);// month d = l + 28 - 31 * System.Math.Floor(m / 4);// day double days = ((m == 3) ? d : d + 31); DateTime result = new DateTime(y, 3, 1).AddDays(days-1); return result; }


Bueno, esto ha sido golpeado hasta la muerte. :) Sin embargo, todavía voy a dar otra respuesta porque necesitaba algo un poco diferente. Esta solución es diferente, ya que devuelve un TimeSpan Business entre el inicio y el final, y puede establecer el horario comercial del día y agregar días festivos. Por lo tanto, puede usarlo para calcular si ocurre dentro de un día, a lo largo de los días, durante los fines de semana e incluso en días festivos. Y puede obtener solo los días hábiles o no solo obteniendo lo que necesita del objeto TimeSpan devuelto. Y la forma en que usa listas de días, puede ver cuán fácil sería agregar la lista de días no laborables si no es el típico sábado y domingo. Y probé durante un año, y parece super rápido.

Solo espero que pegar el código sea preciso. Pero sé que funciona

public static TimeSpan GetBusinessTimespanBetween( DateTime start, DateTime end, TimeSpan workdayStartTime, TimeSpan workdayEndTime, List<DateTime> holidays = null) { if (end < start) throw new ArgumentException("start datetime must be before end datetime."); // Just create an empty list for easier coding. if (holidays == null) holidays = new List<DateTime>(); if (holidays.Where(x => x.TimeOfDay.Ticks > 0).Any()) throw new ArgumentException("holidays can not have a TimeOfDay, only the Date."); var nonWorkDays = new List<DayOfWeek>() { DayOfWeek.Saturday, DayOfWeek.Sunday }; var startTime = start.TimeOfDay; // If the start time is before the starting hours, set it to the starting hour. if (startTime < workdayStartTime) startTime = workdayStartTime; var timeBeforeEndOfWorkDay = workdayEndTime - startTime; // If it''s after the end of the day, then this time lapse doesn''t count. if (timeBeforeEndOfWorkDay.TotalSeconds < 0) timeBeforeEndOfWorkDay = new TimeSpan(); // If start is during a non work day, it doesn''t count. if (nonWorkDays.Contains(start.DayOfWeek)) timeBeforeEndOfWorkDay = new TimeSpan(); else if (holidays.Contains(start.Date)) timeBeforeEndOfWorkDay = new TimeSpan(); var endTime = end.TimeOfDay; // If the end time is after the ending hours, set it to the ending hour. if (endTime > workdayEndTime) endTime = workdayEndTime; var timeAfterStartOfWorkDay = endTime - workdayStartTime; // If it''s before the start of the day, then this time lapse doesn''t count. if (timeAfterStartOfWorkDay.TotalSeconds < 0) timeAfterStartOfWorkDay = new TimeSpan(); // If end is during a non work day, it doesn''t count. if (nonWorkDays.Contains(end.DayOfWeek)) timeAfterStartOfWorkDay = new TimeSpan(); else if (holidays.Contains(end.Date)) timeAfterStartOfWorkDay = new TimeSpan(); // Easy scenario if the times are during the day day. if (start.Date.CompareTo(end.Date) == 0) { if (nonWorkDays.Contains(start.DayOfWeek)) return new TimeSpan(); else if (holidays.Contains(start.Date)) return new TimeSpan(); return endTime - startTime; } else { var timeBetween = end - start; var daysBetween = (int)Math.Floor(timeBetween.TotalDays); var dailyWorkSeconds = (int)Math.Floor((workdayEndTime - workdayStartTime).TotalSeconds); var businessDaysBetween = 0; // Now the fun begins with calculating the actual Business days. if (daysBetween > 0) { var nextStartDay = start.AddDays(1).Date; var dayBeforeEnd = end.AddDays(-1).Date; for (DateTime d = nextStartDay; d <= dayBeforeEnd; d = d.AddDays(1)) { if (nonWorkDays.Contains(d.DayOfWeek)) continue; else if (holidays.Contains(d.Date)) continue; businessDaysBetween++; } } var dailyWorkSecondsToAdd = dailyWorkSeconds * businessDaysBetween; var output = timeBeforeEndOfWorkDay + timeAfterStartOfWorkDay; output = output + new TimeSpan(0, 0, dailyWorkSecondsToAdd); return output; } }

Y aquí está el código de prueba: tenga en cuenta que solo tiene que poner esta función en una clase llamada DateHelper para que funcione el código de prueba.

[TestMethod] public void TestGetBusinessTimespanBetween() { var workdayStart = new TimeSpan(8, 0, 0); var workdayEnd = new TimeSpan(17, 0, 0); var holidays = new List<DateTime>() { new DateTime(2018, 1, 15), // a Monday new DateTime(2018, 2, 15) // a Thursday }; var testdata = new[] { new { expectedMinutes = 0, start = new DateTime(2016, 10, 19, 9, 50, 0), end = new DateTime(2016, 10, 19, 9, 50, 0) }, new { expectedMinutes = 10, start = new DateTime(2016, 10, 19, 9, 50, 0), end = new DateTime(2016, 10, 19, 10, 0, 0) }, new { expectedMinutes = 5, start = new DateTime(2016, 10, 19, 7, 50, 0), end = new DateTime(2016, 10, 19, 8, 5, 0) }, new { expectedMinutes = 5, start = new DateTime(2016, 10, 19, 16, 55, 0), end = new DateTime(2016, 10, 19, 17, 5, 0) }, new { expectedMinutes = 15, start = new DateTime(2016, 10, 19, 16, 50, 0), end = new DateTime(2016, 10, 20, 8, 5, 0) }, new { expectedMinutes = 10, start = new DateTime(2016, 10, 19, 16, 50, 0), end = new DateTime(2016, 10, 20, 7, 55, 0) }, new { expectedMinutes = 5, start = new DateTime(2016, 10, 19, 17, 10, 0), end = new DateTime(2016, 10, 20, 8, 5, 0) }, new { expectedMinutes = 0, start = new DateTime(2016, 10, 19, 17, 10, 0), end = new DateTime(2016, 10, 20, 7, 5, 0) }, new { expectedMinutes = 545, start = new DateTime(2016, 10, 19, 12, 10, 0), end = new DateTime(2016, 10, 20, 12, 15, 0) }, // Spanning multiple weekdays new { expectedMinutes = 835, start = new DateTime(2016, 10, 19, 12, 10, 0), end = new DateTime(2016, 10, 21, 8, 5, 0) }, // Spanning multiple weekdays new { expectedMinutes = 1375, start = new DateTime(2016, 10, 18, 12, 10, 0), end = new DateTime(2016, 10, 21, 8, 5, 0) }, // Spanning from a Thursday to a Tuesday, 5 mins short of complete day. new { expectedMinutes = 1615, start = new DateTime(2016, 10, 20, 12, 10, 0), end = new DateTime(2016, 10, 25, 12, 5, 0) }, // Spanning from a Thursday to a Tuesday, 5 mins beyond complete day. new { expectedMinutes = 1625, start = new DateTime(2016, 10, 20, 12, 10, 0), end = new DateTime(2016, 10, 25, 12, 15, 0) }, // Spanning from a Friday to a Monday, 5 mins beyond complete day. new { expectedMinutes = 545, start = new DateTime(2016, 10, 21, 12, 10, 0), end = new DateTime(2016, 10, 24, 12, 15, 0) }, // Spanning from a Friday to a Monday, 5 mins short complete day. new { expectedMinutes = 535, start = new DateTime(2016, 10, 21, 12, 10, 0), end = new DateTime(2016, 10, 24, 12, 5, 0) }, // Spanning from a Saturday to a Monday, 5 mins short complete day. new { expectedMinutes = 245, start = new DateTime(2016, 10, 22, 12, 10, 0), end = new DateTime(2016, 10, 24, 12, 5, 0) }, // Spanning from a Saturday to a Sunday, 5 mins beyond complete day. new { expectedMinutes = 0, start = new DateTime(2016, 10, 22, 12, 10, 0), end = new DateTime(2016, 10, 23, 12, 15, 0) }, // Times within the same Saturday. new { expectedMinutes = 0, start = new DateTime(2016, 10, 22, 12, 10, 0), end = new DateTime(2016, 10, 23, 12, 15, 0) }, // Spanning from a Saturday to the Sunday next week. new { expectedMinutes = 2700, start = new DateTime(2016, 10, 22, 12, 10, 0), end = new DateTime(2016, 10, 30, 12, 15, 0) }, // Spanning a year. new { expectedMinutes = 143355, start = new DateTime(2016, 10, 22, 12, 10, 0), end = new DateTime(2017, 10, 30, 12, 15, 0) }, // Spanning a year with 2 holidays. new { expectedMinutes = 142815, start = new DateTime(2017, 10, 22, 12, 10, 0), end = new DateTime(2018, 10, 30, 12, 15, 0) }, }; foreach (var item in testdata) { Assert.AreEqual(item.expectedMinutes, DateHelper.GetBusinessTimespanBetween( item.start, item.end, workdayStart, workdayEnd, holidays) .TotalMinutes); } }


Creo que ninguna de las respuestas anteriores es en realidad correcta. Ninguno de ellos resuelve todos los casos especiales, como cuando las fechas comienzan y terminan en la mitad de un fin de semana, cuando la fecha comienza un viernes y termina el próximo lunes, etc. Además de eso, todos redondean los cálculos a toda días, así que si la fecha de inicio es en medio de un sábado, por ejemplo, se restará un día completo de los días hábiles, dando resultados incorrectos ...

De todos modos, aquí está mi solución que es bastante eficiente y simple y funciona para todos los casos. El truco es encontrar el lunes anterior para las fechas de inicio y finalización, y luego hacer una pequeña compensación cuando el inicio y el final suceden durante el fin de semana:

public double WorkDays(DateTime startDate, DateTime endDate){ double weekendDays; double days = endDate.Subtract(startDate).TotalDays; if(days<0) return 0; DateTime startMonday = startDate.AddDays(DayOfWeek.Monday - startDate.DayOfWeek).Date; DateTime endMonday = endDate.AddDays(DayOfWeek.Monday - endDate.DayOfWeek).Date; weekendDays = ((endMonday.Subtract(startMonday).TotalDays) / 7) * 2; // compute fractionary part of weekend days double diffStart = startDate.Subtract(startMonday).TotalDays - 5; double diffEnd = endDate.Subtract(endMonday).TotalDays - 5; // compensate weekenddays if(diffStart>0) weekendDays -= diffStart; if(diffEnd>0) weekendDays += diffEnd; return days - weekendDays; }


De acuerdo. Creo que es hora de publicar la respuesta correcta:

public static double GetBusinessDays(DateTime startD, DateTime endD) { double calcBusinessDays = 1 + ((endD - startD).TotalDays * 5 - (startD.DayOfWeek - endD.DayOfWeek) * 2) / 7; if (endD.DayOfWeek == DayOfWeek.Saturday) calcBusinessDays--; if (startD.DayOfWeek == DayOfWeek.Sunday) calcBusinessDays--; return calcBusinessDays; }

Fuente original:

http://alecpojidaev.wordpress.com/2009/10/29/work-days-calculation-with-c/

Las soluciones de PS publicadas anteriormente me hacen sic por alguna razón.


Defina un método de extensión en DateTime de esta manera:

public static class DateTimeExtensions { public static bool IsWorkingDay(this DateTime date) { return date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday; } }

Entonces, el uso está dentro de una cláusula Where para filtrar una lista más amplia de fechas:

var allDates = GetDates(); // method which returns a list of dates // filter dates by working day''s var countOfWorkDays = allDates .Where(day => day.IsWorkingDay()) .Count() ;


Esta solución evita la iteración, funciona para las diferencias entre los días laborables + ve y -ve e incluye un conjunto de pruebas unitarias para la regresión frente al método más lento de contar los días de la semana. También incluí un método conciso para agregar días de la semana que también funciona de la misma manera no iterativa.

Las pruebas unitarias cubren miles de combinaciones de fechas para probar de manera exhaustiva todas las combinaciones de inicio / fin de semana con intervalos de fechas pequeños y grandes.

Importante : Asumimos que estamos contando días al excluir la fecha de inicio e incluir la fecha de finalización. Esto es importante al contar los días de la semana, ya que los días específicos de inicio / finalización que incluye / excluye afectan el resultado. Esto también asegura que la diferencia entre dos días iguales es siempre cero y que solo incluimos días laborables completos, como generalmente desea que la respuesta sea correcta para cualquier momento en la fecha de inicio actual (a menudo hoy) e incluya la fecha de finalización completa (p. Ej. una fecha de vencimiento).

NOTA: Este código necesita un ajuste adicional para las vacaciones, pero de acuerdo con la suposición anterior, este código debe excluir vacaciones en la fecha de inicio.

Agregar días de la semana:

private static readonly int[,] _addOffset = { // 0 1 2 3 4 {0, 1, 2, 3, 4}, // Su 0 {0, 1, 2, 3, 4}, // M 1 {0, 1, 2, 3, 6}, // Tu 2 {0, 1, 4, 5, 6}, // W 3 {0, 1, 4, 5, 6}, // Th 4 {0, 3, 4, 5, 6}, // F 5 {0, 2, 3, 4, 5}, // Sa 6 }; public static DateTime AddWeekdays(this DateTime date, int weekdays) { int extraDays = weekdays % 5; int addDays = weekdays >= 0 ? (weekdays / 5) * 7 + _addOffset[(int)date.DayOfWeek, extraDays] : (weekdays / 5) * 7 - _addOffset[6 - (int)date.DayOfWeek, -extraDays]; return date.AddDays(addDays); }

Calcular la diferencia del día de la semana:

static readonly int[,] _diffOffset = { // Su M Tu W Th F Sa {0, 1, 2, 3, 4, 5, 5}, // Su {4, 0, 1, 2, 3, 4, 4}, // M {3, 4, 0, 1, 2, 3, 3}, // Tu {2, 3, 4, 0, 1, 2, 2}, // W {1, 2, 3, 4, 0, 1, 1}, // Th {0, 1, 2, 3, 4, 0, 0}, // F {0, 1, 2, 3, 4, 5, 0}, // Sa }; public static int GetWeekdaysDiff(this DateTime dtStart, DateTime dtEnd) { int daysDiff = (int)(dtEnd - dtStart).TotalDays; return daysDiff >= 0 ? 5 * (daysDiff / 7) + _diffOffset[(int) dtStart.DayOfWeek, (int) dtEnd.DayOfWeek] : 5 * (daysDiff / 7) - _diffOffset[6 - (int) dtStart.DayOfWeek, 6 - (int) dtEnd.DayOfWeek]; }

Descubrí que la mayoría de las otras soluciones en el desbordamiento de la pila eran lentas (iterativas) o demasiado complejas y muchas simplemente incorrectas. La moraleja de la historia es ... ¡¡No confíes en ella a menos que la hayas probado exhaustivamente !!

Pruebas unitarias basadas en las pruebas NUnit Combinatorial y la extensión ShouldBe NUnit.

[TestFixture] public class DateTimeExtensionsTests { /// <summary> /// Exclude start date, Include end date /// </summary> /// <param name="dtStart"></param> /// <param name="dtEnd"></param> /// <returns></returns> private IEnumerable<DateTime> GetDateRange(DateTime dtStart, DateTime dtEnd) { Console.WriteLine(@"dtStart={0:yy-MMM-dd ddd}, dtEnd={1:yy-MMM-dd ddd}", dtStart, dtEnd); TimeSpan diff = dtEnd - dtStart; Console.WriteLine(diff); if (dtStart <= dtEnd) { for (DateTime dt = dtStart.AddDays(1); dt <= dtEnd; dt = dt.AddDays(1)) { Console.WriteLine(@"dt={0:yy-MMM-dd ddd}", dt); yield return dt; } } else { for (DateTime dt = dtStart.AddDays(-1); dt >= dtEnd; dt = dt.AddDays(-1)) { Console.WriteLine(@"dt={0:yy-MMM-dd ddd}", dt); yield return dt; } } } [Test, Combinatorial] public void TestGetWeekdaysDiff( [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)] int startDay, [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)] int endDay, [Values(7)] int startMonth, [Values(7)] int endMonth) { // Arrange DateTime dtStart = new DateTime(2016, startMonth, startDay); DateTime dtEnd = new DateTime(2016, endMonth, endDay); int nDays = GetDateRange(dtStart, dtEnd) .Count(dt => dt.DayOfWeek != DayOfWeek.Saturday && dt.DayOfWeek != DayOfWeek.Sunday); if (dtEnd < dtStart) nDays = -nDays; Console.WriteLine(@"countBusDays={0}", nDays); // Act / Assert dtStart.GetWeekdaysDiff(dtEnd).ShouldBe(nDays); } [Test, Combinatorial] public void TestAddWeekdays( [Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)] int startDay, [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 30)] int weekdays) { DateTime dtStart = new DateTime(2016, 7, startDay); DateTime dtEnd1 = dtStart.AddWeekdays(weekdays); // ADD dtStart.GetWeekdaysDiff(dtEnd1).ShouldBe(weekdays); DateTime dtEnd2 = dtStart.AddWeekdays(-weekdays); // SUBTRACT dtStart.GetWeekdaysDiff(dtEnd2).ShouldBe(-weekdays); } }


He tenido una tarea así antes y tengo la solución. Evitaría enumerar todos los días intermedios cuando sea evitable, que es el caso aquí. Ni siquiera menciono crear un montón de instancias DateTime, como vi en una de las respuestas anteriores. Esto es realmente una pérdida de poder de procesamiento. Especialmente en la situación del mundo real, cuando tienes que examinar intervalos de tiempo de varios meses. Ver mi código, con comentarios, a continuación.

/// <summary> /// Calculates number of business days, taking into account: /// - weekends (Saturdays and Sundays) /// - bank holidays in the middle of the week /// </summary> /// <param name="firstDay">First day in the time interval</param> /// <param name="lastDay">Last day in the time interval</param> /// <param name="bankHolidays">List of bank holidays excluding weekends</param> /// <returns>Number of business days during the ''span''</returns> public static int BusinessDaysUntil(this DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays) { firstDay = firstDay.Date; lastDay = lastDay.Date; if (firstDay > lastDay) throw new ArgumentException("Incorrect last day " + lastDay); TimeSpan span = lastDay - firstDay; int businessDays = span.Days + 1; int fullWeekCount = businessDays / 7; // find out if there are weekends during the time exceedng the full weeks if (businessDays > fullWeekCount*7) { // we are here to find out if there is a 1-day or 2-days weekend // in the time interval remaining after subtracting the complete weeks int firstDayOfWeek = (int) firstDay.DayOfWeek; int lastDayOfWeek = (int) lastDay.DayOfWeek; if (lastDayOfWeek < firstDayOfWeek) lastDayOfWeek += 7; if (firstDayOfWeek <= 6) { if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval businessDays -= 2; else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval businessDays -= 1; } else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval businessDays -= 1; } // subtract the weekends during the full weeks in the interval businessDays -= fullWeekCount + fullWeekCount; // subtract the number of bank holidays during the time interval foreach (DateTime bankHoliday in bankHolidays) { DateTime bh = bankHoliday.Date; if (firstDay <= bh && bh <= lastDay) --businessDays; } return businessDays; }

Edit by Slauma, agosto de 2011

¡Gran respuesta! Sin embargo, hay un pequeño error. Me tomo la libertad de editar esta respuesta ya que el respondedor está ausente desde 2009.

El código anterior asume que DayOfWeek.Sunday tiene el valor 7 que no es el caso. El valor es en realidad 0 . Lleva a un cálculo incorrecto si, por ejemplo, firstDay y lastDay son ambos el mismo domingo. El método devuelve 1 en este caso, pero debería ser 0 .

La solución más fácil para este error: reemplace en el código sobre las líneas donde firstDayOfWeek y lastDayOfWeek se declaran de la siguiente manera:

int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)firstDay.DayOfWeek; int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)lastDay.DayOfWeek;

Ahora el resultado es:

  • Viernes a viernes -> 1
  • De sábado a sábado -> 0
  • De domingo a domingo -> 0
  • Viernes a sábado -> 1
  • Viernes a domingo -> 1
  • Viernes a lunes -> 2
  • De sábado a lunes -> 1
  • Domingo a lunes -> 1
  • De lunes a lunes -> 1

Sé que esta pregunta ya está resuelta, pero pensé que podría ofrecer una respuesta más directa que pueda ayudar a otros visitantes en el futuro.

Aquí está mi opinión:

public int GetWorkingDays(DateTime from, DateTime to) { var dayDifference = (int)to.Subtract(from).TotalDays; return Enumerable .Range(1, dayDifference) .Select(x => from.AddDays(x)) .Count(x => x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday); }

Esta fue mi presentación original:

public int GetWorkingDays(DateTime from, DateTime to) { var totalDays = 0; for (var date = from; date < to; date = date.AddDays(1)) { if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday) totalDays++; } return totalDays; }


Tenía problemas para encontrar una versión sólida de TSQL de este código. A continuación se muestra esencialmente una conversión del código C # aquí con la adición de la tabla de vacaciones que se debe utilizar para precalcular las vacaciones.

CREATE TABLE dbo.Holiday ( HolidayDt DATE NOT NULL, Name NVARCHAR(50) NOT NULL, IsWeekday BIT NOT NULL, CONSTRAINT PK_Holiday PRIMARY KEY (HolidayDt) ) GO CREATE INDEX IDX_Holiday ON Holiday (HolidayDt, IsWeekday) GO CREATE function dbo.GetBusinessDays ( @FirstDay datetime, @LastDay datetime ) RETURNS INT AS BEGIN DECLARE @BusinessDays INT, @FullWeekCount INT SELECT @FirstDay = CONVERT(DATETIME,CONVERT(DATE,@FirstDay)) , @LastDay = CONVERT(DATETIME,CONVERT(DATE,@LastDay)) IF @FirstDay > @LastDay RETURN NULL; SELECT @BusinessDays = DATEDIFF(DAY, @FirstDay, @LastDay) + 1 SELECT @FullWeekCount = @BusinessDays / 7; -- find out if there are weekends during the time exceedng the full weeks IF @BusinessDays > (@FullWeekCount * 7) BEGIN -- we are here to find out if there is a 1-day or 2-days weekend -- in the time interval remaining after subtracting the complete weeks DECLARE @firstDayOfWeek INT, @lastDayOfWeek INT; SELECT @firstDayOfWeek = DATEPART(DW, @FirstDay), @lastDayOfWeek = DATEPART(DW, @LastDay); IF @lastDayOfWeek < @firstDayOfWeek SELECT @lastDayOfWeek = @lastDayOfWeek + 7; IF @firstDayOfWeek <= 6 BEGIN IF (@lastDayOfWeek >= 7) --Both Saturday and Sunday are in the remaining time interval BEGIN SELECT @BusinessDays = @BusinessDays - 2 END ELSE IF @lastDayOfWeek>=6 --Only Saturday is in the remaining time interval BEGIN SELECT @BusinessDays = @BusinessDays - 1 END END ELSE IF @firstDayOfWeek <= 7 AND @lastDayOfWeek >=7 -- Only Sunday is in the remaining time interval BEGIN SELECT @BusinessDays = @BusinessDays - 1 END END -- subtract the weekends during the full weeks in the interval DECLARE @Holidays INT; SELECT @Holidays = COUNT(*) FROM Holiday WHERE HolidayDt BETWEEN @FirstDay AND @LastDay AND IsWeekday = CAST(1 AS BIT) SELECT @BusinessDays = @BusinessDays - (@FullWeekCount + @FullWeekCount) -- - @Holidays RETURN @BusinessDays END


Usé el siguiente código para incluir también en cuenta los días festivos:

public class WorkingDays { public List<DateTime> GetHolidays() { var client = new WebClient(); var json = client.DownloadString("https://www.gov.uk/bank-holidays.json"); var js = new JavaScriptSerializer(); var holidays = js.Deserialize <Dictionary<string, Holidays>>(json); return holidays["england-and-wales"].events.Select(d => d.date).ToList(); } public int GetWorkingDays(DateTime from, DateTime to) { var totalDays = 0; var holidays = GetHolidays(); for (var date = from.AddDays(1); date <= to; date = date.AddDays(1)) { if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday && !holidays.Contains(date)) totalDays++; } return totalDays; } } public class Holidays { public string division { get; set; } public List<Event> events { get; set; } } public class Event { public DateTime date { get; set; } public string notes { get; set; } public string title { get; set; } }

Y pruebas unitarias:

[TestClass] public class WorkingDays { [TestMethod] public void SameDayIsZero() { var service = new WorkingDays(); var from = new DateTime(2013, 8, 12); Assert.AreEqual(0, service.GetWorkingDays(from, from)); } [TestMethod] public void CalculateDaysInWorkingWeek() { var service = new WorkingDays(); var from = new DateTime(2013, 8, 12); var to = new DateTime(2013, 8, 16); Assert.AreEqual(4, service.GetWorkingDays(from, to), "Mon - Fri = 4"); Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 13)), "Mon - Tues = 1"); } [TestMethod] public void NotIncludeWeekends() { var service = new WorkingDays(); var from = new DateTime(2013, 8, 9); var to = new DateTime(2013, 8, 16); Assert.AreEqual(5, service.GetWorkingDays(from, to), "Fri - Fri = 5"); Assert.AreEqual(2, service.GetWorkingDays(from, new DateTime(2013, 8, 13)), "Fri - Tues = 2"); Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 12)), "Fri - Mon = 1"); } [TestMethod] public void AccountForHolidays() { var service = new WorkingDays(); var from = new DateTime(2013, 8, 23); Assert.AreEqual(0, service.GetWorkingDays(from, new DateTime(2013, 8, 26)), "Fri - Mon = 0"); Assert.AreEqual(1, service.GetWorkingDays(from, new DateTime(2013, 8, 27)), "Fri - Tues = 1"); } }


Voy a compartir mi solución. Me funcionó, tal vez simplemente no me doy cuenta / sé que hay un error. Empecé obteniendo la primera semana incompleta si hay alguna. una semana completa era de domingo para el sábado, así que si el (int) _now.DayOfWeek no era 0 (domingo), la primera semana estaba incompleta.

Solo restar 1 a la cuenta de primeras semanas para el primer sábado de la semana y luego agregarlo al nuevo recuento;

Luego recibo la última semana incompleta, luego resta 1 por el domingo y luego agrego el nuevo conteo.

Luego, finalmente, se agregó el número de semanas completas multiplicadas por 5 (días laborables) al nuevo recuento.

public int RemoveNonWorkingDays(int numberOfDays){ int workingDays = 0; int firstWeek = 7 - (int)_now.DayOfWeek; if(firstWeek < 7){ if(firstWeek > numberOfDays) return numberOfDays; workingDays += firstWeek-1; numberOfDays -= firstWeek; } int lastWeek = numberOfDays % 7; if(lastWeek > 0){ numberOfDays -= lastWeek; workingDays += lastWeek - 1; } workingDays += (numberOfDays/7)*5; return workingDays; }


I believe this could be a simpler way:

public int BusinessDaysUntil(DateTime start, DateTime end, params DateTime[] bankHolidays) { int tld = (int)((end - start).TotalDays) + 1; //including end day int not_buss_day = 2 * (tld / 7); //Saturday and Sunday int rest = tld % 7; //rest. if (rest > 0) { int tmp = (int)start.DayOfWeek - 1 + rest; if (tmp == 6 || start.DayOfWeek == DayOfWeek.Sunday) not_buss_day++; else if (tmp > 6) not_buss_day += 2; } foreach (DateTime bankHoliday in bankHolidays) { DateTime bh = bankHoliday.Date; if (!(bh.DayOfWeek == DayOfWeek.Saturday || bh.DayOfWeek == DayOfWeek.Sunday) && (start <= bh && bh <= end)) { not_buss_day++; } } return tld - not_buss_day; }


Based on the comment marked as answer and patch recommended , as well as -> This version wants to convert the Days to Business-Hours ... Considers Same day hours as well.

/// <summary> /// Calculates number of business days, taking into account: /// - weekends (Saturdays and Sundays) /// - bank holidays in the middle of the week /// </summary> /// <param name="firstDay">First day in the time interval</param> /// <param name="lastDay">Last day in the time interval</param> /// <param name="bankHolidays">List of bank holidays excluding weekends</param> /// <returns>Number of business hours during the ''span''</returns> public static int BusinessHoursUntil(DateTime firstDay, DateTime lastDay, params DateTime[] bankHolidays) { var original_firstDay = firstDay; var original_lastDay = lastDay; firstDay = firstDay.Date; lastDay = lastDay.Date; if (firstDay > lastDay) return -1; //// throw new ArgumentException("Incorrect last day " + lastDay); TimeSpan span = lastDay - firstDay; int businessDays = span.Days + 1; int fullWeekCount = businessDays / 7; // find out if there are weekends during the time exceedng the full weeks if (businessDays > fullWeekCount * 7) { // we are here to find out if there is a 1-day or 2-days weekend // in the time interval remaining after subtracting the complete weeks int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)firstDay.DayOfWeek; int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)lastDay.DayOfWeek; if (lastDayOfWeek < firstDayOfWeek) lastDayOfWeek += 7; if (firstDayOfWeek <= 6) { if (lastDayOfWeek >= 7)// Both Saturday and Sunday are in the remaining time interval businessDays -= 2; else if (lastDayOfWeek >= 6)// Only Saturday is in the remaining time interval businessDays -= 1; } else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)// Only Sunday is in the remaining time interval businessDays -= 1; } // subtract the weekends during the full weeks in the interval businessDays -= fullWeekCount + fullWeekCount; if (bankHolidays != null && bankHolidays.Any()) { // subtract the number of bank holidays during the time interval foreach (DateTime bankHoliday in bankHolidays) { DateTime bh = bankHoliday.Date; if (firstDay <= bh && bh <= lastDay) --businessDays; } } int total_business_hours = 0; if (firstDay.Date == lastDay.Date) {//If on the same day, go granular with Hours from the Orginial_*Day values total_business_hours = (int)(original_lastDay - original_firstDay).TotalHours; } else {//Convert Business-Days to TotalHours total_business_hours = (int)(firstDay.AddDays(businessDays).AddHours(firstDay.Hour) - firstDay).TotalHours; } return total_business_hours; }


Esta es una solución genérica.

startdayvalue es el número de día de la fecha de inicio.

weekendday_1 es el día numner del fin de semana.

número de día - MON - 1, TUE - 2, ... SAT - 6, SUN - 7.

la diferencia es la diferencia entre dos fechas ...

Ejemplo: Fecha de inicio: 4 de abril de 2013, fecha de finalización: 14 de abril de 2013

Diferencia: 10, startdayvalue: 4, weekendday_1: 7 (si SUNDAY es un fin de semana para ti)

Esto le dará varias vacaciones.

No del día hábil = (Diferencia + 1) - vacaciones1

if (startdayvalue > weekendday_1) { if (difference > ((7 - startdayvalue) + weekendday_1)) { holiday1 = (difference - ((7 - startdayvalue) + weekendday_1)) / 7; holiday1 = holiday1 + 1; } else { holiday1 = 0; } } else if (startdayvalue < weekendday_1) { if (difference > (weekendday_1 - startdayvalue)) { holiday1 = (difference - (weekendday_1 - startdayvalue)) / 7; holiday1 = holiday1 + 1; } else if (difference == (weekendday_1 - startdayvalue)) { holiday1 = 1; } else { holiday1 = 0; } } else { holiday1 = difference / 7; holiday1 = holiday1 + 1; }


Here is an approach if you are using MVC. I have also calculated national holidays or any festive days to be excluded by fetching it from holidayscalendar which you will need to make one.

foreach (DateTime day in EachDay(model)) { bool key = false; foreach (LeaveModel ln in holidaycalendar) { if (day.Date == ln.Date && day.DayOfWeek != DayOfWeek.Saturday && day.DayOfWeek != DayOfWeek.Sunday) { key = true; break; } } if (day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday) { key = true; } if (key != true) { leavecount++; } }

Leavemodel es una lista aquí


Here is one very simple solution for this problem. We have starting date, end date and "for loop" for encreasing the day and calculating to see if it''s a workday or a weekend by converting to string DayOfWeek.

class Program { static void Main(string[] args) { DateTime day = new DateTime(); Console.Write("Inser your end date (example: 01/30/2015): "); DateTime endDate = DateTime.Parse(Console.ReadLine()); int numberOfDays = 0; for (day = DateTime.Now.Date; day.Date < endDate.Date; day = day.Date.AddDays(1)) { string dayToString = Convert.ToString(day.DayOfWeek); if (dayToString != "Saturday" && dayToString != "Sunday") numberOfDays++; } Console.WriteLine("Number of working days (not including local holidays) between two dates is "+numberOfDays); } }


Here is the function which we can use to calculate business days between two date. I''m not using holiday list as it can vary accross country/region.

If we want to use it anyway we can take third argument as list of holiday and before incrementing count we should check that list does not contains d

public static int GetBussinessDaysBetweenTwoDates(DateTime StartDate, DateTime EndDate) { if (StartDate > EndDate) return -1; int bd = 0; for (DateTime d = StartDate; d < EndDate; d = d.AddDays(1)) { if (d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday) bd++; } return bd; }


Here''s yet another idea - this method allows to specify any working week and holidays.

The idea here is that we find the core of the date range from the first first working day of the week to the last weekend day of the week. This enables us to calculate the whole weeks easily ( without iterating over all of the dates). All we need to do then is to add the working days that fall before the start and end of this core range.

public static int CalculateWorkingDays( DateTime startDate, DateTime endDate, IList<DateTime> holidays, DayOfWeek firstDayOfWeek, DayOfWeek lastDayOfWeek) { // Make sure the defined working days run contiguously if (lastDayOfWeek < firstDayOfWeek) { throw new Exception("Last day of week cannot fall before first day of week!"); } // Create a list of the days of the week that make-up the weekend by working back // from the firstDayOfWeek and forward from lastDayOfWeek to get the start and end // the weekend var weekendStart = lastDayOfWeek == DayOfWeek.Saturday ? DayOfWeek.Sunday : lastDayOfWeek + 1; var weekendEnd = firstDayOfWeek == DayOfWeek.Sunday ? DayOfWeek.Saturday : firstDayOfWeek - 1; var weekendDays = new List<DayOfWeek>(); var w = weekendStart; do { weekendDays.Add(w); if (w == weekendEnd) break; w = (w == DayOfWeek.Saturday) ? DayOfWeek.Sunday : w + 1; } while (true); // Force simple dates - no time startDate = startDate.Date; endDate = endDate.Date; // Ensure a progessive date range if (endDate < startDate) { var t = startDate; startDate = endDate; endDate = t; } // setup some working variables and constants const int daysInWeek = 7; // yeah - really! var actualStartDate = startDate; // this will end up on startOfWeek boundary var actualEndDate = endDate; // this will end up on weekendEnd boundary int workingDaysInWeek = daysInWeek - weekendDays.Count; int workingDays = 0; // the result we are trying to find int leadingDays = 0; // the number of working days leading up to the firstDayOfWeek boundary int trailingDays = 0; // the number of working days counting back to the weekendEnd boundary // Calculate leading working days // if we aren''t on the firstDayOfWeek we need to step forward to the nearest if (startDate.DayOfWeek != firstDayOfWeek) { var d = startDate; do { if (d.DayOfWeek == firstDayOfWeek || d >= endDate) { actualStartDate = d; break; } if (!weekendDays.Contains(d.DayOfWeek)) { leadingDays++; } d = d.AddDays(1); } while(true); } // Calculate trailing working days // if we aren''t on the weekendEnd we step back to the nearest if (endDate >= actualStartDate && endDate.DayOfWeek != weekendEnd) { var d = endDate; do { if (d.DayOfWeek == weekendEnd || d < actualStartDate) { actualEndDate = d; break; } if (!weekendDays.Contains(d.DayOfWeek)) { trailingDays++; } d = d.AddDays(-1); } while(true); } // Calculate the inclusive number of days between the actualStartDate and the actualEndDate var coreDays = (actualEndDate - actualStartDate).Days + 1; var noWeeks = coreDays / daysInWeek; // add together leading, core and trailing days workingDays += noWeeks * workingDaysInWeek; workingDays += leadingDays; workingDays += trailingDays; // Finally remove any holidays that fall within the range. if (holidays != null) { workingDays -= holidays.Count(h => h >= startDate && (h <= endDate)); } return workingDays; }


I just improved @Alexander and @Slauma answer to support a business week as a parameter, for cases where saturday is a business day, or even cases where there is just a couple of days of the week that are considered business days:

/// <summary> /// Calculate the number of business days between two dates, considering: /// - Days of the week that are not considered business days. /// - Holidays between these two dates. /// </summary> /// <param name="fDay">First day of the desired ''span''.</param> /// <param name="lDay">Last day of the desired ''span''.</param> /// <param name="BusinessDaysOfWeek">Days of the week that are considered to be business days, if NULL considers monday, tuesday, wednesday, thursday and friday as business days of the week.</param> /// <param name="Holidays">Holidays, if NULL, considers no holiday.</param> /// <returns>Number of business days during the ''span''</returns> public static int BusinessDaysUntil(this DateTime fDay, DateTime lDay, DayOfWeek[] BusinessDaysOfWeek = null, DateTime[] Holidays = null) { if (BusinessDaysOfWeek == null) BusinessDaysOfWeek = new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }; if (Holidays == null) Holidays = new DateTime[] { }; fDay = fDay.Date; lDay = lDay.Date; if (fDay > lDay) throw new ArgumentException("Incorrect last day " + lDay); int bDays = (lDay - fDay).Days + 1; int fullWeekCount = bDays / 7; int fullWeekCountMult = 7 - WeekDays.Length; // Find out if there are weekends during the time exceedng the full weeks if (bDays > (fullWeekCount * 7)) { int fDayOfWeek = (int)fDay.DayOfWeek; int lDayOfWeek = (int)lDay.DayOfWeek; if (fDayOfWeek > lDayOfWeek) lDayOfWeek += 7; // If they are the same, we already covered it right before the Holiday subtraction if (lDayOfWeek != fDayOfWeek) { // Here we need to see if any of the days between are considered business days for (int i = fDayOfWeek; i <= lDayOfWeek; i++) if (!WeekDays.Contains((DayOfWeek)(i > 6 ? i - 7 : i))) bDays -= 1; } } // Subtract the days that are not in WeekDays[] during the full weeks in the interval bDays -= (fullWeekCount * fullWeekCountMult); // Subtract the number of bank holidays during the time interval bDays = bDays - Holidays.Select(x => x.Date).Count(x => fDay <= x && x <= lDay); return bDays; }


I searched a lot for a, easy to digest, algorithm to calculate the working days between 2 dates, and also to exclude the national holidays, and finally I decide to go with this approach:

public static int NumberOfWorkingDaysBetween2Dates(DateTime start,DateTime due,IEnumerable<DateTime> holidays) { var dic = new Dictionary<DateTime, DayOfWeek>(); var totalDays = (due - start).Days; for (int i = 0; i < totalDays + 1; i++) { if (!holidays.Any(x => x == start.AddDays(i))) dic.Add(start.AddDays(i), start.AddDays(i).DayOfWeek); } return dic.Where(x => x.Value != DayOfWeek.Saturday && x.Value != DayOfWeek.Sunday).Count(); }

Basically I wanted to go with each date and evaluate my conditions:

  1. Is not Saturday
  2. Is not Sunday
  3. Is not national holiday

but also I wanted to avoid iterating dates.

By running and measuring the time need it to evaluate 1 full year, I go the following result:

static void Main(string[] args) { var start = new DateTime(2017, 1, 1); var due = new DateTime(2017, 12, 31); var sw = Stopwatch.StartNew(); var days = NumberOfWorkingDaysBetween2Dates(start, due,NationalHolidays()); sw.Stop(); Console.WriteLine($"Total working days = {days} --- time: {sw.Elapsed}"); Console.ReadLine(); // result is: // Total working days = 249-- - time: 00:00:00.0269087 }


Since I can''t comment. There is one more issue with the accepted solution where bank holidays are subtracted even when they are situated in the weekend. Seeing how other input is checked, it is only fitting that this is as well.

The foreach should therefore be:

// subtract the number of bank holidays during the time interval foreach (DateTime bankHoliday in bankHolidays) { DateTime bh = bankHoliday.Date; // Do not subtract bank holidays when they fall in the weekend to avoid double subtraction if (bh.DayOfWeek == DayOfWeek.Saturday || bh.DayOfWeek == DayOfWeek.Sunday) continue; if (firstDay <= bh && bh <= lastDay) --businessDays; }


int BusinessDayDifference(DateTime Date1, DateTime Date2) { int Sign = 1; if (Date2 > Date1) { Sign = -1; DateTime TempDate = Date1; Date1 = Date2; Date2 = TempDate; } int BusDayDiff = (int)(Date1.Date - Date2.Date).TotalDays; if (Date1.DayOfWeek == DayOfWeek.Saturday) BusDayDiff -= 1; if (Date2.DayOfWeek == DayOfWeek.Sunday) BusDayDiff -= 1; int Week1 = GetWeekNum(Date1); int Week2 = GetWeekNum(Date2); int WeekDiff = Week1 - Week2; BusDayDiff -= WeekDiff * 2; foreach (DateTime Holiday in Holidays) if (Date1 >= Holiday && Date2 <= Holiday) BusDayDiff--; BusDayDiff *= Sign; return BusDayDiff; } private int GetWeekNum(DateTime Date) { return (int)(Date.AddDays(-(int)Date.DayOfWeek).Ticks / TimeSpan.TicksPerDay / 7); }


public enum NonWorkingDays { SaturdaySunday = 0, FridaySaturday = 1 }; public int getBusinessDates(DateTime dateSt, DateTime dateNd, NonWorkingDays nonWorkingDays = NonWorkingDays.SaturdaySunday) { List<DateTime> datelist = new List<DateTime>(); while (dateSt.Date < dateNd.Date) { datelist.Add((dateSt = dateSt.AddDays(1))); } if (nonWorkingDays == NonWorkingDays.SaturdaySunday) { return datelist.Count(d => d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Friday); } else { return datelist.Count(d => d.DayOfWeek != DayOfWeek.Friday && d.DayOfWeek != DayOfWeek.Saturday); } }


using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { DateTime start = new DateTime(2014, 1, 1); DateTime stop = new DateTime(2014, 12, 31); int totalWorkingDays = GetNumberOfWorkingDays(start, stop); Console.WriteLine("There are {0} working days.", totalWorkingDays); } private static int GetNumberOfWorkingDays(DateTime start, DateTime stop) { TimeSpan interval = stop - start; int totalWeek = interval.Days / 7; int totalWorkingDays = 5 * totalWeek; int remainingDays = interval.Days % 7; for (int i = 0; i <= remainingDays; i++) { DayOfWeek test = (DayOfWeek)(((int)start.DayOfWeek + i) % 7); if (test >= DayOfWeek.Monday && test <= DayOfWeek.Friday) totalWorkingDays++; } return totalWorkingDays; } } }