6

Is there a simple way or framework to get all weekends within a date range in C#?

Is it possible to do with LINQ as well?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 3
    I suppose it's not too straightforward but it should be possible (including with LINQ). Good luck! – Jeroen Vannevel Jul 25 '14 at 18:52
  • 2
    Superman, by now you should know that the answer to "is possible" is almost always "yes". I suspect you want someone to show you how. You should ask that question instead if that's what you're seeking. – mason Jul 25 '14 at 18:55

3 Answers3

22

If you make a way to enumerate all days, you can use LINQ to filter to weekends:

IEnumerable<DateTime> GetDaysBetween(DateTime start, DateTime end)
{
    for (DateTime i = start; i < end; i = i.AddDays(1))
    {
        yield return i;
    }
}

var weekends = GetDaysBetween(DateTime.Today, DateTime.Today.AddDays(365))
    .Where(d => d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mitch
  • 21,223
  • 6
  • 63
  • 86
  • 3
    Wonder why this was downvoted, looks fine to me and while it's more power hungry than some of the other solutions (that avoid enumerating all days just to filter them) it is a very simple / clean / maintainable one on a problem that is unlikely to ever be a bottleneck unless the OP is working on thouthands of years periods. Upvoting to compensate. – Ronan Thibaudau Jul 25 '14 at 19:17
  • 1
    [The Fastest Gun in the West](http://meta.stackexchange.com/questions/9731/fastest-gun-in-the-west-problem) shoot himself on the foot: It was downvoted (not by me) because when the answer was first posted it was badly formatted and incomplete. There are no revisions because Mitch fixed it fast enough to make SO not consider it a revision but not as fast for others to see it and downvote it – Carlos Muñoz Jul 25 '14 at 19:33
  • Yep, wasn't even trying to go quick... hit tab space while I was still writing it. – Mitch Jul 25 '14 at 19:35
  • 2
    @RonanThibaudau, this is actually something I have tested previously. Despite the apparent decrease in performance you might imagine, I found that the naïve version actually outperformed the "smart" version in most tests. Those tests were focusing on date modulus, so I can't say whether they would apply equally when using the `DayOfWeek` enumeration. I do agree, however, that "programs should be written for people to read, and only incidentally for machines to execute." – Mitch Jul 25 '14 at 19:40
  • @Mitch i was actually siding with that, the decrease in performance would be minor (with 5 additional calls to adddays per week vs none for the smart version), so it's possible to be made faster but we're talking extremely tiny amounts that wouldn't matter except in a tighy loop (i just wrote a quick specific version for weekends and tested it against yours, 100 times over 1000 years, your version is at 2700ms vs 600ms for mine, same results, but it still doesn't matter as most people don't try to get all weekends for the next 1000 years 100 times in a row) – Ronan Thibaudau Jul 25 '14 at 20:01
  • This answer is mentioned in Stack Overflow blog post: [The next step in ecommerce? Replatform with APIs and micro frontends](https://stackoverflow.blog/2022/12/12/the-next-step-in-ecommerce-replatform-with-apis-and-micro-frontends/) – Arulkumar Dec 13 '22 at 14:47
3

I found how to do it.

http://www.dotnetjalps.com/2011/06/finding-saturdaysunday-between-date.html

namespace DatimeApplication
{
   class Program
   {
       static void Main(string[] args)
       {
             DateTime startDate=new DateTime(2011,3,1);
             DateTime endDate = DateTime.Now;

             TimeSpan diff = endDate - startDate;
             int days = diff.Days;
             for (var i = 0; i <= days; i++)
             {
                 var testDate = startDate.AddDays(i);
                 switch (testDate.DayOfWeek)
                 {
                     case DayOfWeek.Saturday:
                     case DayOfWeek.Sunday:
                         Console.WriteLine(testDate.ToShortDateString());
                         break;
                 }
             }
           Console.ReadLine();
       }
   }
}
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • The link is broken: *"Hmm. We’re having trouble finding that site. We can’t connect to the server at www.dotnetjalps.com."*. (The domain name [***isn't*** a misspelling](https://www.zoominfo.com/c/dotnetjalps/356919335).) – Peter Mortensen Nov 03 '22 at 15:58
1

That's not really difficult to code... Here's an efficient iterator:

public static IEnumerable<DateTime> GetWeekends(DateTime startDate, DateTime endDate)
{
    startDate = startDate.Date;
    endDate = endDate.Date;

    if (endDate < startDate)
        yield break;

    var currentDate = startDate;

    // Advance to next Saturday
    switch (currentDate.DayOfWeek)
    {
        case DayOfWeek.Saturday:
            break;

        case DayOfWeek.Sunday:
            yield return currentDate;
            currentDate = currentDate.AddDays(6);
            break;

        default:
            currentDate = currentDate.AddDays(DayOfWeek.Saturday - currentDate.DayOfWeek);
            break;
    }

    while (currentDate <= endDate)
    {
        yield return currentDate;

        currentDate = currentDate.AddDays(1);
        if (currentDate <= endDate)
            yield return currentDate;

        currentDate = currentDate.AddDays(6);
    }
}
Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158