Week Of Year

This algorithm finds the current week number in a year according to ISO-8601 standard.



									/*****Please include following header files*****/
// iostream
/***********************************************/

/*****Please use following namespaces*****/
// std
/*****************************************/

struct Date {
	unsigned int Year;
	char Month;
	char Day;
};

enum DayOfWeek
{
	Sunday,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday
};

static bool IsLeapYear(unsigned int year) {
	return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}

static char DaysInMonth(unsigned int year, char month) {
	char daysInMonth;

	if (month == 4 || month == 6 || month == 9 || month == 11)
	{
		daysInMonth = 30;
	}
	else if (month == 2)
	{
		if (IsLeapYear(year))
		{
			daysInMonth = 29;
		}
		else
		{
			daysInMonth = 28;
		}
	}
	else
	{
		daysInMonth = 31;
	}

	return daysInMonth;
}

static unsigned int DateToDays(Date date) {
	return ((date.Year * 365) + IsLeapYear(date.Year)) + DaysInMonth(date.Year, date.Month) + date.Day;
}

static int CompareDate(Date date1, Date date2) {
	unsigned int d1Days = DateToDays(date1);
	unsigned int d2Days = DateToDays(date2);

	if (d1Days > d2Days)
		return 1;
	else if (d1Days < d2Days)
		return -1;
	else
		return 0;
}

static DayOfWeek GetDayOfWeek(unsigned int year, char month, char day) {
	char monthTable[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };

	year -= (unsigned int)((month < 3) ? 1 : 0);

	return (DayOfWeek)((year + year / 4 - year / 100 + year / 400 + monthTable[month - 1] + day) % 7);
}

static int GetISODayOfWeek(unsigned int year, char month, char day)
{
	switch (GetDayOfWeek(year, month, day))
	{
	case DayOfWeek::Monday:
		return 1;
	case DayOfWeek::Tuesday:
		return 2;
	case DayOfWeek::Wednesday:
		return 3;
	case DayOfWeek::Thursday:
		return 4;
	case DayOfWeek::Friday:
		return 5;
	case DayOfWeek::Saturday:
		return 6;
	case DayOfWeek::Sunday:
		return 7;
	default:
		return -1;
	}
}

static Date GetWeekOne(int year)
{
	Date date = { year, 1, 4 };
	int ISODay = GetISODayOfWeek(year, 1, 4);
	int addDays = 1 - ISODay;

	if (addDays < 0) {
		int pAddDays = -addDays;
		bool b = pAddDays > 4;
		date.Year -= b;
		date.Month = b ? 12 : 1;
		date.Day = b ? 31 - (pAddDays - 4) : date.Day - (pAddDays - 4);
	} else {
		date.Day += addDays;
	}

	return date;
}

static char GetWeekOfYear(Date d)
{
	Date weekOne;
	unsigned int year = d.Year;

	int i = CompareDate(d, { year, 12, 29 });

	if (i == 1 || i == 0)
	{
		weekOne = GetWeekOne(year + 1);

		if (CompareDate(d, weekOne) == -1)
			weekOne = GetWeekOne(year);
		else
			year++;
	}
	else
	{
		weekOne = GetWeekOne(year);

		if (CompareDate(d, weekOne) == -1)
			weekOne = GetWeekOne(--year);
	}

	return (DateToDays(d) - DateToDays(weekOne)) / 7 + 1;
}
								


Example

									char weekNumber = GetWeekOfYear({ 2015, 12, 5 });
								


Output

									49