The way you're doing the week number caculation is wrong as
Vivek[
^] already pointed out in his answer the correct way to do this is to use
Calendar.GetWeekOfYear
. In my example below I used the
GregorianCalendar
with
GregorianCalendarType.Localized
. For the method
GetWeekOfYear
to work correctly though you will have to use
CalendarWeekRule
to specify how a week is started when transitioning from one year to the next. Equally important is how the first
DayOfWeek
is defined in your locale. In my country Monday is the correct day, but that may differ where you are.
Depending on the value of
CalendarWeekRule
there are different results to be obtained. Weeks may either span across a year boundary or my have less than 7 days. The following list exlains how this value can be used to define the behavior:
- FirstDay: Indicates that the first week of the year starts on the first day of the year and ends before the following designated first day of the week. The value is 0. This value ensures that a week does not span two years.
- FirstFullWeek: Indicates that the first week of the year begins on the first occurrence of the designated first day of the week on or after the first day of the year. The value is 1. This value will make sure that there will never be any odd weeks in the list of calculated weeks, but a week may span across the year boundary.
- FirstFourDayWeek: Indicates that the first week of the year is the first week with four or more days before the designated first day of the week. The value is 2.
Disclaimer!: The following code is is in C# and not in VB.net. My proficiency in VB.net not good so I used the language I usually code in. I hope you'll be able to understand what I did. If you have any specific question about parts of the code you don't understand, I'll be happy to try to explain it to you. Not using VB.net has
nothing to do with a like or dislike of that language.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace WeekCount
{
class Program
{
static void Main(string[] args)
{
DateTime start = new DateTime(2010, 1, 1);
DateTime end = new DateTime(2010, 12, 31);
DateTime current = start;
GregorianCalendar calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
CalendarWeekRule rule = CalendarWeekRule.FirstDay;
DayOfWeek firstDayOfWeek = DayOfWeek.Monday;
List<Week> weeks = Week.GetAllWeeks(
start,
end,
rule,
firstDayOfWeek,
GregorianCalendarTypes.Localized);
List<Week> oddWeeks = weeks.FindAll(delegate(Week week)
{
return week.IsOdd;
});
int total = weeks.Count;
String verb1 = total > 1 ? "are a total of" : "is";
String plural1 = total > 1 ? "s" : "";
int odd = oddWeeks.Count;
String verb2 = odd > 1 || odd == 0 ? "are" : "is an";
String plural2 = odd > 1 || odd == 0 ? "s" : "";
String formatStatistics = "There {0} {1} week{2} in the list of which {3} {4} odd week{5}.\n";
Console.WriteLine(formatStatistics,
new Object[] {verb1, total, plural1, odd, verb2, plural2});
String formatLoop = "Start: {0:ddd MMM dd.} End: {1:ddd MMM dd.} Number: {2:00} Days: {3:00} Year: {4:####}";
foreach (Week week in oddWeeks)
{
Console.WriteLine(formatLoop, new Object[] {
week.Start,
week.End,
week.Number,
week.Days,
week.Year}
);
}
Console.ReadLine();
}
}
public class Week
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public int Number { get; set; }
public int Days { get { return End.Subtract(Start).Days + 1; } }
public bool IsOdd { get { return Days < 7; } }
public int Year { get { return Start.Year; } }
public Week(DateTime start, DateTime end, int weekNumber)
{
this.Start = new DateTime(start.Year, start.Month, start.Day);
this.End = new DateTime(end.Year, end.Month, end.Day);
this.Number = weekNumber;
}
public bool Contains(DateTime date)
{
DateTime tmp = new DateTime(date.Year, date.Month, date.Day);
return Start <= tmp && tmp <= End;
}
public static List<Week> GetAllWeeks(
DateTime start,
DateTime end,
CalendarWeekRule rule,
DayOfWeek firstDayOfWeek,
GregorianCalendarTypes calendarType)
{
GregorianCalendar calendar = new GregorianCalendar(calendarType);
List<Week> result = new List<Week>();
DateTime currentDate = start;
int currentWeekNumber = calendar.GetWeekOfYear(currentDate, rule, firstDayOfWeek);
do
{
currentDate = currentDate.AddDays(-1);
} while (currentWeekNumber == calendar.GetWeekOfYear(currentDate, rule, firstDayOfWeek));
currentDate = currentDate.AddDays(1);
Week currentWeek = null;
DateTime startDateOfWeek = currentDate;
int nextWeekNumber = currentWeekNumber;
while (currentDate < end)
{
currentDate = currentDate.AddDays(1);
if (currentWeekNumber != calendar.GetWeekOfYear(currentDate, rule, firstDayOfWeek))
{
currentWeek = new Week(startDateOfWeek, currentDate.AddDays(-1), currentWeekNumber);
result.Add(currentWeek);
currentWeekNumber = calendar.GetWeekOfYear(currentDate, rule, firstDayOfWeek);
startDateOfWeek = currentDate;
}
}
if (result.Count == 0 || startDateOfWeek != result.Last().Start)
{
while (currentWeekNumber == calendar.GetWeekOfYear(currentDate, rule, firstDayOfWeek))
{
currentDate = currentDate.AddDays(1);
}
result.Add(new Week(startDateOfWeek, currentDate.AddDays(-1), currentWeekNumber));
}
return result;
}
}
}