Reputation: 355
I want to get only weeks for the whole year where I want to get the start date (Monday) and end date (Friday) in C#.
For example: 1/52
= 02 Jan (Monday) - 09 Jan (Sunday)
2/52
= 10 Jan (Monday) - 17 Jan (Sunday)
and so on.
I can get current week dates but no idea how to get for the year.
// We Set the Monday as the first day of the week.
DayOfWeek day = datetime.DayOfWeek;
int days = day - DayOfWeek.Monday;
if (days == -1)
{
days = 6; // this is when we have sunday as a DayOfWeek day
}
DateTime start = datetime.AddDays(-days);
DateTime end = start.AddDays(6);
Upvotes: 0
Views: 4030
Reputation: 5156
I think this should work for Gregorian calendars and takes into account different cultures:
public static IList<DateTime> GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
{
var lastDateOfYear = new DateTime(year, 12, 31);
var firstDate = new DateTime(year, 1, 1);
var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
while (firstDate.DayOfWeek != dayOfWeek)
{
firstDate = firstDate.AddDays(1);
}
var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);
var firstDayOfWeekDates = new List<DateTime>();
firstDayOfWeekDates.Add(firstDate);
var currentDate = firstDate;
for (int i = 0; i < numberOfWeeksInYear; i++)
{
var weekLater = currentDate.AddDays(7);
if (weekLater.Year == year)
{
currentDate = weekLater;
firstDayOfWeekDates.Add(currentDate);
}
}
return firstDayOfWeekDates;
}
You can test this with a console app like this (make the method static):
static void Main(string[] args)
{
var ci = new CultureInfo("en-GB");
var dates = GetFirstDayOfWeekDates(ci, DateTime.Now.Year);
foreach (var dt in dates)
{
Console.WriteLine("Date: " + dt.ToShortDateString());
}
Console.ReadLine();
}
It brings back the following:
If you want to include the end date of the week as well then you can tweak this slightly by adding a new class called WeekDate:
public class WeekDate
{
public DateTime StartOfWeek { get; set; }
public DateTime EndOfWeek { get; set; }
}
GetFirstDayOfWeekDates then becomes:
public static IList<WeekDate> GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
{
var lastDateOfYear = new DateTime(year, 12, 31);
var firstDate = new DateTime(year, 1, 1);
var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
while (firstDate.DayOfWeek != dayOfWeek)
{
firstDate = firstDate.AddDays(1);
}
var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);
var firstDayOfWeekDates = new List<WeekDate>();
firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = firstDate, EndOfWeek = firstDate.AddDays(6) });
var currentDate = firstDate;
for (int i = 0; i < numberOfWeeksInYear; i++)
{
var weekLater = currentDate.AddDays(7);
if (weekLater.Year == year)
{
currentDate = currentDate.AddDays(7);
firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = currentDate, EndOfWeek = currentDate.AddDays(6) });
}
}
return firstDayOfWeekDates;
}
Which returns:
Upvotes: 0
Reputation: 2216
You can use methods below to calculate start day of any week of any year
public static DateTime StartOfNthWeekOfYear(int year, int weekNumber, DayOfWeek firstDayOfWeek)
{
if(weekNumber < 1)
{
throw new ArgumentOutOfRangeException(nameof(weekNumber));
}
DateTime startOfWeek = StartOfFirstWeekOfYear(year, firstDayOfWeek).AddDays((weekNumber - 1) * 7);
DateTime endOfWeek = startOfWeek.AddDays(6);
if(endOfWeek.Year != year || startOfWeek.Year != year)
{
throw new ArgumentOutOfRangeException(nameof(weekNumber));
}
return startOfWeek;
}
public static DateTime StartOfFirstWeekOfYear(int year, DayOfWeek firstDayOfWeek)
{
DateTime startOfYear = new DateTime(year, 1, 1);
if (startOfYear.DayOfWeek != firstDayOfWeek)
{
return StartOfWeek(startOfYear, firstDayOfWeek).AddDays(7);
}
return startOfYear;
}
public static DateTime StartOfWeek(DateTime value, DayOfWeek firstDayOfWeek)
{
if (value.DayOfWeek != firstDayOfWeek)
{
return value.AddDays(-((7 + (int)value.DayOfWeek - (int)firstDayOfWeek) % 7));
}
return value;
}
Upvotes: 0
Reputation: 12629
Without making it complicated you can simply use while
like below.
while (datetime.DayOfWeek != DayOfWeek.Monday)
{
datetime= datetime.AddDays(1);
}
DateTime start = datetime;
DateTime end = start.AddDays(6);
Or you want to find week from the week index 1/52
for any year
then write function like below. Use it like GetWeek(1, 2020)
to get 06.01.2020 - 12.01.2020
. Format it as per your requirement.
public DateTime GetNextMonday(DateTime datetime)
{
return datetime.AddDays((7 - (int)datetime.DayOfWeek + (int)DayOfWeek.Monday) % 7);
}
public string GetWeek(int week, int year)
{
var start = GetNextMonday(new DateTime(year, 1, 1).AddDays((week-1)*7));
var end = start.AddDays(6);
return start.ToShortDateString() + " - " + end.ToShortDateString();
}
Upvotes: 1
Reputation: 1
As far as I have understood, probably this will help, I tried the below and it displayed for me the start and end dates for the specified years:
DateTime starting = new DateTime(2020, 1, 1);
DateTime ending = new DateTime(2020, 12, 1);
DateTime currentDay = starting;
DateTime start = currentDay;
DateTime end = currentDay;
while (ending.Year >= currentDay.Year)
{
if (currentDay.DayOfWeek == DayOfWeek.Monday)
{
start = currentDay;
end = start.AddDays(6);
currentDay = end;
Console.WriteLine(start + "(" + start.DayOfWeek + ")");
Console.WriteLine(end + "(" + end.DayOfWeek + ")");
}
else
{
currentDay = currentDay.AddDays(1);
}
}
Upvotes: 0