Of course, looking at my WHS diary, I realised that the first of January is not always in week 1, but is sometimes week 52/53 of the previous year, and also the last few days of December may be counted as the first week in the next year.
Thus all the solutions given so far, while some of them (including my own) will give a week number based on 1st Jan, they will not calculate the week of the year used as standard.
Also, it seems weeks do officially run from Monday to Sunday (even though we all know that Sunday is the first day of the week!)
A quick Google found this
ISO Standard[
^]. This says that week one of any year starts on the Monday before the first Thursday of the year. Or in other words, week one is the week in which the 4th of January falls (Monday to Sunday).
The initial calculation is similar to my first solution, but instead of adding 7, add 10 (and we have to adjust wday to 7 if it is 0 for Sunday).
Then if this calculation returns 0 the day is part of the last week of the preceding year. If it returns 53 we have to determine if it is part of week 1 of the next year, or if the year really does have 53 weeks (there are 71 in every 400 years - 5, 6 or 7 years apart).
Anyway, without further ado, here is my code for calculating this ISO week of the year:
int GetWeek
(
struct tm* date
)
{
if (NULL == date)
{
return 0; }
if (::mktime(date) < 0) {
return 0; }
int monToSun = (date->tm_wday == 0) ? 7 : date->tm_wday; int week = ((date->tm_yday + 11 - monToSun) / 7);
if (week == 0)
{
tm lastDay = { 0 };
lastDay.tm_mday = 31;
lastDay.tm_mon = 11;
lastDay.tm_year = date->tm_year - 1;
lastDay.tm_hour = 12;
week = GetWeek(&lastDay);
}
else if (week == 53)
{
int lastDay = date->tm_wday + 31 - date->tm_mday;
if (lastDay == 5) {
int daysInYear = date->tm_yday + 32 - date->tm_mday; if (daysInYear < 366)
{
week = 1;
}
}
else if (lastDay != 4) {
week = 1;
}
}
return week;
}
int GetWeek
( int day, int month, int year )
{
tm date = { 0 };
date.tm_mday = day;
date.tm_mon = month - 1;
date.tm_year = year - 1900;
date.tm_hour = 12;
return GetWeek(&date);
}
Example usage:
int week = GetWeek(15,5,2013);
int GetCurrentWeek()
{
tm today;
time_t now;
time(&now);
errno_t error = ::localtime_s(&today, &now);
return GetWeek(&today);
}
All the best.
Regards,
Ian.