2011-07-25 29 views
6

Necesito encontrar los próximos tres días hábiles disponibles para una aplicación de programación. Lo que está disponible depende de las fechas excluidas en una tabla. Entonces ... siempre que la fecha no esté en mi mesa y no sea sábado o domingo, quiero los próximos tres. Me gustaría encontrar una manera eficiente de hacer esto.LINQ: ¿cómo obtener los próximos tres días hábiles excluyendo las fechas en la tabla?

Necesito devolver un List<DateTime>. La tabla es simple: ExcludedDates tiene un ID y un DateTime con la fecha excluida.

Me gustaría tener una sola expresión de consulta LINQ pero no puedo entenderlo ... gracias a todos por adelantado y me disculpo si esto es trivial u obvio - no es para mí.

+0

No estoy seguro de si puede hacer esto solo con linq debido al requisito de exclusión de fin de semana. Es posible que deba ejecutar esto en un ciclo limitado comprobando cada semana hasta que haya reunido tres días abiertos. – Brain2000

+0

Echa un vistazo a esta publicación. Tiene la parte del fin de semana de lo que estás buscando. http://stackoverflow.com/questions/1617049/calculate-the-number-of-business-days-between-two-dates –

+0

Y para ampliar eso, podría obtener su lista de fechas excluidas y hacer otra '.Where (d =>! dateList.Contains (d)) '(o algo así ...) y luego un' .Take (3) ' – GalacticCowboy

Respuesta

8

Prueba esto ...

DateTime start = DateTime.Now.Date; 
    var result = Enumerable.Range(1, 10) // make this '10' higher if necessary (I assume you only exclude non-workingdays like Christmas and Easter) 
        .Select(offset => start.AddDays(offset)) 
        .Where(date => !(date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek== DayOfWeek.Sunday)) 
        .Where(d=> !exceptionTable.Any(date => date == d)) 
        .Take(3).ToList(); 
+0

agrega .ToList y eres bueno – Grozz

+0

linq es tan genial – echo

+0

Esto se parece a esto puede funcionar para mi Sin embargo, el segundo .Where() me está tirando. Any() usa los valores de mi tabla de excepción como entrada para el lambda, pero no sé cómo acceder a las fechas generadas hacia el principio en el predicado. La d var en el código no hace referencia a nada (el nombre "d" no existe en el contexto actual). Perdón por las preguntas de novato, pero no puedo entender esto:/ – CircusNinja

0

Esto supone que un mes será razonable dependiendo de las fechas excluidas.

 DateTime date = DateTime.Today; 
     // first generate all dates in the month of 'date' 
     var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n)); 
     // then filter the only the start of weeks 
     var results = (from d in dates 
         where d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Saturday && !excludes.Any(i => i.DateTime.Date == d.Date) && date < d 
         select d).Take(3); 
0
List<DateTime> result = (from i in Enumerable.Range(1, excludeTable.Rows.Count + 6) 
     let date = inputDate.AddDays(i) 
     where date.DayOfWeek != DayOfWeek.Saturday && 
       date.DayOfWeek != DayOfWeek.Sunday && 
       !excludeTable.Rows.Cast<DataRow>().Select(r => (DateTime) r["ExcludeDate"]).Contains(date) 
     select date).Take(3).ToList(); 

excludeTable.Rows.Count + 6 es para cubrir el peor de los casos donde saltar sobre todas las cosas en el excludeTable y luego hay que pasar por alto otro fin de semana.

0
var excludedList = new List<long>() { DateTime.Parse("2011-07-27").Ticks }; 

var week = new List<long>(){ 
       DateTime.Now.Date.Ticks, 
       DateTime.Now.Date.AddDays(1).Ticks, 
       DateTime.Now.Date.AddDays(2).Ticks, 
       DateTime.Now.Date.AddDays(3).Ticks, 
       DateTime.Now.Date.AddDays(4).Ticks, 
       DateTime.Now.Date.AddDays(5).Ticks, 
       DateTime.Now.Date.AddDays(6).Ticks, 
       DateTime.Now.Date.AddDays(7).Ticks, 
       DateTime.Now.Date.AddDays(8).Ticks 
      }; 

var available = (from d in week.Except(excludedList) 
       where new DateTime(d).DayOfWeek != DayOfWeek.Saturday && new DateTime(d).DayOfWeek != DayOfWeek.Sunday 
       select new DateTime(d)).Take(3); 

foreach (var a in available) 
    Console.WriteLine(a.ToString()); 
Cuestiones relacionadas