8

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.

Lost in Alabama
  • 1,653
  • 10
  • 16
DarrylGodden
  • 1,526
  • 5
  • 25
  • 44

5 Answers5

31

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
        });
spender
  • 117,338
  • 33
  • 229
  • 351
3

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); 
IrishChieftain
  • 15,108
  • 7
  • 50
  • 91
  • Doesn't this just get the current week number? I think OP is looking for a list of weeks, i.e. 9/11 - 9/17, etc. – James Johnson Sep 09 '11 at 15:38
  • Valid point :) The rest is just looping thru weeks of year and populating the DDL items. What I've outlined in my answer though is the "gotcha"... – IrishChieftain Sep 09 '11 at 15:43
3

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.

Cubicle.Jockey
  • 3,288
  • 1
  • 19
  • 31
  • If you like this version still select senders as the answer, as mine was just an update, but I wasn't sure if a comment with a big code chunk on his was appropriate. – Cubicle.Jockey Sep 09 '11 at 16:13
3

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();
}
mayo
  • 3,845
  • 1
  • 32
  • 42
0

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();

    }
DaveK
  • 4,509
  • 3
  • 33
  • 33