2015-03-20 2 views
0

У меня есть функция таблицы UDF в SQL, которая функционирует следующим образомПолучить диапазон будний из двух дат

select * from dbo.GetWeekdayRange(convert(datetime, '11/03/2015', 103), convert(datetime, '31/03/2015', 103)) 

Выход:

WeekStartDate    WeekEndDate 
------------------------------------------------- 
2015-03-11 00:00:00.000 2015-03-15 00:00:00.000 
2015-03-16 00:00:00.000 2015-03-22 00:00:00.000 
2015-03-23 00:00:00.000 2015-03-29 00:00:00.000 
2015-03-30 00:00:00.000 2015-03-31 00:00:00.000 

есть ли такая функция доступна в C#? Я также пытался использовать LINQ, но не смог добиться успеха. Я попытался найти его, но я не нашел ни одного из них.

ответ

3

Это может быть воспроизведен в C# довольно легко, я уверен, что есть более эффективное решение, но это работает:

public static IEnumerable<DateRange> GetWeekdayRange(DateTime startDate, DateTime endDate, DayOfWeek weekEndsOn = DayOfWeek.Sunday) 
{ 
    var currStartDate = startDate; 
    var currDate = startDate; 
    while(currDate<endDate) 
    { 
     while(currDate.DayOfWeek != weekEndsOn && currDate<endDate) 
     { 
      currDate = currDate.AddDays(1); 
     } 
     yield return new DateRange{ WeekStartDate = currStartDate,WeekEndDate = currDate}; 
     currStartDate = currDate.AddDays(1); 
     currDate = currStartDate; 
    } 
} 

public struct DateRange 
{ 
    public DateTime WeekStartDate{get;set;} 
    public DateTime WeekEndDate{get;set;} 
} 

Код испытания

var start = new DateTime(2015,3,11); 
var end = new DateTime(2015,3,31); 

var range = GetWeekdayRange(start,end); 
foreach(var val in range) 
{ 
    Console.WriteLine("{0:yyyy-MM-dd} - {1:yyyy-MM-dd}",val.WeekStartDate,val.WeekEndDate); 
} 

Выход:

2015-03-11 - 2015-03-15
2015-03-16 - 2015-03-22
2015-03-23 ​​- 2015-03-29
2015-03-30 - 2015-03-31

Живой пример: http://rextester.com/DGSX37215

если вы действительно хотите больше LINQ-еу решение, вы можете это сделать - мне труднее читать и понимать, что происходит, но он дает тот же результат. Он использует календарь группы список дат в недели, а затем выбирает Min и Max из групп

public static IEnumerable<DateRange> GetWeekdayRange(DateTime startDate, DateTime endDate, DayOfWeek weekStartsOn = DayOfWeek.Monday) 
{ 
    var diff = endDate.Subtract(startDate).Days; 
    var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar; 
    var range = Enumerable.Range(0,diff+1).Select(v => startDate.AddDays(v)) 
         .Select(d => new {Date=d, WeekNumber=cal.GetWeekOfYear(d, System.Globalization.CalendarWeekRule.FirstDay, weekStartsOn) }) 
         .GroupBy(g => g.WeekNumber); 

    return range.Select(g => new DateRange{WeekStartDate=g.Min(v => v.Date), WeekEndDate= g.Max(v => v.Date)}); 
} 

Живой пример: http://rextester.com/CXSXC66880

+0

Ваш выход неправильно 11-15 16-22 23 -29 .. где день окончания недели? –

+0

@RameshRajendran - еще раз взгляните на вопрос - его немного вводит в заблуждение, но выход OP имеет субботу и воскресенье. Он ищет дату начала недели (понедельника) и дату окончания недели (воскресенье) – Jamiec

+0

Спасибо большое, что отлично работает. Однако вы можете уточнить, что вы подразумеваете под эффективным решением? – Hitesh

Смежные вопросы