帮助找出一周的周数? [英] Help to find out the Week number of year?

查看:102
本文介绍了帮助找出一周的周数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何找到给定日期的周数





示例:



2010年1月1日 - 1周



22/2/2010 - 9周





喜欢这个?????

How can I find the week number of a given date


Example :

1/1/2010 - 1 week

22/2/2010 - 9 week


like this ?????

推荐答案

周数来自%W规格。例如:



The week number comes from the %W spec. For example:

CString sDir = COleDateTime::GetCurrentTime().Format( "\\%Y\\%W" );





[不看]如果你看一下strftime()的帮助,我想你会得到更多信息。



[without looking] I think you will get further information if you look at the help for strftime().


当然,看看我的WHS日记,我意识到1月1日并不总是在第1周,但有时是前一年的52/53周,也是最后几个十二月的日子可算作明年的第一周。



因此到目前为止所有的解决方案,而其中一些(包括我自己的)将给出根据1月1日的一周数字,他们不会计算作为标准使用的一年中的一周。



此外,似乎周数从周一到周日正式运行(即使我们都知道周日是一周的第一天!)



一个快速的Google发现了这个 ISO标准 [ ^ ]。这表示任何一周的第一周都是在一年的第一个星期四之前的星期一开始。或者换句话说,第一周是1月4日(星期一到星期日)的一周。



初始计算类似于我的第一个解决方案,但是而不是添加7,添加10(如果周日为0,我们必须将wday调整为7)。



然后如果此计算返回0,那么这一天就是一部分上一年的最后一周。如果它返回53,我们必须确定它是否是下一年第1周的一部分,或者如果这一年确实有53周(每400年有71个 - 相隔5,6或7年)。



无论如何,不​​用多说了,这是我计算今年ISO周的代码:



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; // or -1 or throw exception
	}
	if (::mktime(date) < 0) // Make sure _USE_32BIT_TIME_T is NOT defined.
	{
		return 0; // or -1 or throw exception
	}
	// The basic calculation:
	// {Day of Year (1 to 366) + 10 - Day of Week (Mon = 1 to Sun = 7)} / 7
	int monToSun = (date->tm_wday == 0) ? 7 : date->tm_wday; // Adjust zero indexed week day
	int week = ((date->tm_yday + 11 - monToSun) / 7); // Add 11 because yday is 0 to 365.

	// Now deal with special cases:
	// A) If calculated week is zero, then it is part of the last week of the previous year.
	if (week == 0)
	{
		// We need to find out if there are 53 weeks in previous year.
		// Unfortunately to do so we have to call mktime again to get the information we require.
		// Here we can use a slight cheat - reuse this function!
		// (This won't end up in a loop, because there's no way week will be zero again with these values).
		tm lastDay = { 0 };
		lastDay.tm_mday = 31;
		lastDay.tm_mon = 11;
		lastDay.tm_year = date->tm_year - 1;
		// We set time to sometime during the day (midday seems to make sense)
		// so that we don't get problems with daylight saving time.
		lastDay.tm_hour = 12;
		week = GetWeek(&lastDay);
	}
	// B) If calculated week is 53, then we need to determine if there really are 53 weeks in current year
	//    or if this is actually week one of the next year.
	else if (week == 53)
	{
		// We need to find out if there really are 53 weeks in this year,
		// There must be 53 weeks in the year if:
		// a) it ends on Thurs (year also starts on Thurs, or Wed on leap year).
		// b) it ends on Friday and starts on Thurs (a leap year).
		// In order not to call mktime again, we can work this out from what we already know!
		int lastDay = date->tm_wday + 31 - date->tm_mday;
		if (lastDay == 5) // Last day of the year is Friday
		{
			// How many days in the year?
			int daysInYear = date->tm_yday + 32 - date->tm_mday; // add 32 because yday is 0 to 365
			if (daysInYear < 366)
			{
				// If 365 days in year, then the year started on Friday
				// so there are only 52 weeks, and this is week one of next year.
				week = 1;
			}
		}
		else if (lastDay != 4) // Last day is NOT Thursday
		{
			// This must be the first week of next year
			week = 1;
		}
		// Otherwise we really have 53 weeks!
	}
	return week;
}

int GetWeek
	(          // Valid values:
	int day,   // 1 to 31
	int month, // 1 to 12.  1 = Jan.
	int year   // 1970 to 3000
	)
{
	tm date = { 0 };
	date.tm_mday = day;
	date.tm_mon = month - 1;
	date.tm_year = year - 1900;
	// We set time to sometime during the day (midday seems to make sense)
	// so that we don't get problems with daylight saving time.
	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);
}





一切顺利。



问候,

Ian。



All the best.

Regards,
Ian.


你可以通过Boost解决同样的问题,

例如见下面的代码:

The same problem you can solve by Boost,
for example see following code:
#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>

using namespace std;
using namespace boost::gregorian;

int main()
{
 date_duration dd = date(2000, 1, 1) - date(1900, 1, 1);
 date_duration dd1(7);
 dd = date(2100, 1, 1) - date(2000, 1, 1);
 dd = (dd.days() < 7) ? dd1 : dd; 
 int number_of_weeks = (0==(dd.days()%7)) ? dd.days()/7 : (dd.days()/7 + 1);
 cout << "The number of weeks between two dates is" << number_of_weeks << endl;
}


这篇关于帮助找出一周的周数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆