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.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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
});
Method 2
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);
Method 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.
Method 4
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();
}
Method 5
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();
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0