una sumar restar horas habiles fechas fecha dias actual c# f# date

c# - restar - sumar fechas typescript



Agregar días a una fecha pero sin incluir los fines de semana (9)

Dada una fecha, ¿cómo puedo agregarle un número de días, pero excluir los fines de semana? Por ejemplo, dado 11/12/2008 (miércoles) y agregando cinco resultará en 11/19/2008 (miércoles) en lugar de 17/11/2008 (lunes).

Puedo pensar en una solución simple como recorrer cada día para agregar y verificar si es un fin de semana, pero me gustaría ver si hay algo más elegante. También me interesaría cualquier solución de F #.


Dado el número del día original en el año D y el día original en la semana W y el número de días laborables para agregar N, el siguiente número de día de la semana es

W + N % 5.

El día siguiente en el año (sin cheque envolvente) es

D + ((N / 5) * 7) + N % 5).

Esto supone que tienes una división entera.


int daysToAdd = weekDaysToAdd + ((weekDaysToAdd / 5) * 2) + (((origDate.DOW + (weekDaysToAdd % 5)) >= 5) ? 2 : 0);

Esto es; el número de días "reales" para agregar es el número de días de la semana que está especificando, más el número de semanas completas que están en ese total (de ahí el weekDaysToAdd / 5) multiplicado por dos (dos días en el fin de semana); más un posible descuento de dos días si el día original de la semana más el número de días laborables para agregar "dentro" de la semana (de ahí el mod 5 de weekDaysToAdd) es mayor o igual a 5 (es decir, es un día de fin de semana).

Nota: esto funciona suponiendo que 0 = lunes, 2 = martes, ... 6 = domingo. También; esto no funciona en intervalos de días de semana negativos.


public DateTime AddBusinessDays(DateTime dt, int nDays) { int weeks = nDays / 5; nDays %= 5; while(dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday) dt = dt.AddDays(1); while (nDays-- > 0) { dt = dt.AddDays(1); if (dt.DayOfWeek == DayOfWeek.Saturday) dt = dt.AddDays(2); } return dt.AddDays(weeks*7); }


Creé una extensión que le permite agregar o restar días hábiles. Use un número negativo de días hábiles para restar. Parece que funciona en todos los casos.

namespace Extensions.DateTime { public static class BusinessDays { public static System.DateTime AddBusinessDays(this System.DateTime source, int businessDays) { var dayOfWeek = businessDays < 0 ? ((int)source.DayOfWeek - 12) % 7 : ((int)source.DayOfWeek + 6) % 7; switch (dayOfWeek) { case 6: businessDays--; break; case -6: businessDays++; break; } return source.AddDays(businessDays + ((businessDays + dayOfWeek) / 5) * 2); } } }

Ejemplo:

using System; using System.Windows.Forms; using Extensions.DateTime; namespace AddBusinessDaysTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); label1.Text = DateTime.Now.AddBusinessDays(5).ToString(); label2.Text = DateTime.Now.AddBusinessDays(-36).ToString(); } } }


Esto es mejor si alguien está buscando una solución TSQL . Una línea de código y funciona con negativos.

CREATE FUNCTION[dbo].[AddBusinessDays](@Date date,@n INT)RETURNS DATE AS BEGIN DECLARE @d INT;SET @d=4-SIGN(@n)*(4-DATEPART(DW,@Date)); RETURN DATEADD(D,@n+((ABS(@n)+@d-2)/5)*2*SIGN(@n)-@d/7,@Date)END



La fórmula será: día laborable (fecha, número de días, (día de la semana (1)))

Prueba esto. Esto ayudará.


Utilizaría esta extensión, recuerda que es un método de extensión para ponerla en una clase estática.

Uso:

var dateTime = DateTime.Now.AddBusinessDays(5);

Código:

namespace ExtensionMethods { public static class MyExtensionMethods { public static DateTime AddBusinessDays(this DateTime current, int days) { var sign = Math.Sign(days); var unsignedDays = Math.Abs(days); for (var i = 0; i < unsignedDays; i++) { do { current = current.AddDays(sign); } while (current.DayOfWeek == DayOfWeek.Saturday || current.DayOfWeek == DayOfWeek.Sunday); } return current; } } }


Sin complicar demasiado el algoritmo, puedes crear un método de extensión como este:

public static DateTime AddWorkingDays(this DateTime date, int daysToAdd) { while (daysToAdd > 0) { date = date.AddDays(1); if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday) { daysToAdd -= 1; } } return date; }