DarrylGodden
DarrylGodden

Reputation: 1534

Get a list of weeks for a year - with dates

I've been racking my brains over this, but it's late on a Friday and I'm going round in circles.

I need to create a list of working weeks for a drop down list, with the week number as the value. So the code would output:

Monday 22nd August - Friday 26th September
Monday 29th August - Friday 2 September
Monday 5th September - Friday 9 September

etc..

For the whole year. Any ideas how I would achieve this?

Thanks.

Upvotes: 8

Views: 17976

Answers (5)

user687474
user687474

Reputation:

You can use the Week class of the Time Period Library for .NET:

DateTime start = DateTime.Now.Date;
DateTime end = start.AddYears( 1 );
Week week = new Week( start );
while ( week.Start < end )
{
  Console.WriteLine( "week " + week );
  week = week.GetNextWeek();
}

Upvotes: 3

spender
spender

Reputation: 120410

I think the code below complies with ISO 8601:

var jan1 = new DateTime(DateTime.Today.Year , 1, 1);
//beware different cultures, see other answers
var startOfFirstWeek = jan1.AddDays(1 - (int)(jan1.DayOfWeek));
var weeks=
    Enumerable
        .Range(0,54)
        .Select(i => new {
            weekStart = startOfFirstWeek.AddDays(i * 7)
        })
        .TakeWhile(x => x.weekStart.Year <= jan1.Year)
        .Select(x => new {
            x.weekStart,
            weekFinish=x.weekStart.AddDays(4)
        })
        .SkipWhile(x => x.weekFinish < jan1.AddDays(1) )
        .Select((x,i) => new {
            x.weekStart,
            x.weekFinish,
            weekNum=i+1
        });

Upvotes: 31

Cubicle.Jockey
Cubicle.Jockey

Reputation: 3328

Just updating what Spender put, because I wanted to make the output of your Datetimes more towards what you wanted.

DateTime jan1 = new DateTime(DateTime.Today.Year, 1, 1);
//beware different cultures, see other answers
DateTime startOfFirstWeek = jan1.AddDays(1 - (int)(jan1.DayOfWeek));
var weeks=
    Enumerable
        .Range(0,54)
        .Select(i => new {
            weekStart = startOfFirstWeek.AddDays(i * 7)
        })
        .TakeWhile(x => x.weekStart.Year <= jan1.Year)
        .Select(x => new {
            x.weekStart,
            weekFinish=x.weekStart.AddDays(4)
        })
        .SkipWhile(x => x.weekFinish.Year < jan1.Year)
        .Select((x,i) => new {
            WeekStart = x.weekStart.ToString("dddd, d, MMMM"),
            WeekFinish = x.weekFinish.ToString("dddd, d, MMMM"),
            weekNum=i+1
        });

The change to correct the formatting to what you wanted is in the last select of the anonymous object.

Upvotes: 3

DaveK
DaveK

Reputation: 4607

You may need to tweak this a bit, but it should get you what you need:

static void Main(string[] args)
    {
        List<DateTime[]> weeks = new List<DateTime[]>();

        DateTime beginDate = new DateTime(2011, 01, 01);
        DateTime endDate = new DateTime(2012, 01, 01);

        DateTime monday = DateTime.Today;
        DateTime friday = DateTime.Today;

        while (beginDate < endDate)
        {
            beginDate = beginDate.AddDays(1);

            if (beginDate.DayOfWeek == DayOfWeek.Monday)
            {
                monday = beginDate;
            }
            else if (beginDate.DayOfWeek == DayOfWeek.Friday)
            {
                friday = beginDate;
            }
            else if (beginDate.DayOfWeek == DayOfWeek.Saturday)
            {
                weeks.Add(new DateTime[] { monday, friday });
            }
        }

        for (int x = 0; x < weeks.Count; x++)
        {
            Console.WriteLine(weeks[x][0].Date.ToShortDateString() + " - " + weeks[x][1].Date.ToShortDateString());
        }

        Console.ReadLine();

    }

Upvotes: 0

IrishChieftain
IrishChieftain

Reputation: 15253

Bear in mind, that week calculations are done differently in different cultures and there is not a bug if you see week number 53!

using System.Globalization;

CultureInfo cultInfo = CultureInfo.CurrentCulture;
int weekNumNow = cultInfo.Calendar.GetWeekOfYear(DateTime.Now,
                     cultInfo.DateTimeFormat.CalendarWeekRule,
                         cultInfo.DateTimeFormat.FirstDayOfWeek); 

Upvotes: 3

Related Questions