根据给定的年份和周数计算开始和结束日期/时间
Calculate the starting and ending date/time from a given year and week number
如何计算给定年份的开始和结束日期/时间(YYYY-MM-DD HH:MM:::SS)和一年中的ISO周数?
在再次问这种问题之前,我搜索了SO。当然,在 SO 上有一些关于从(年、周号)到(日期时间)的转换的线程。但是他们通过说Perl,PHP,JAVA,SQL,C#,.NET,Excel和其他编程语言来回答,除了C/C++。
恐
怕使用简单的C++没有简短的解决方案。但是,编写解决方案不应该是一项艰巨的工作。您只需要处理特殊情况(例如第一周和最后一周,二月,闰年)。一种方法可以是
- 从一年的周数中,获取该年的
day numbers
(即开始和结束日数)。(在这里照顾第一周和最后一周) - 现在很容易找到月份和日期与
day numbers
谎言。(在这里照顾二月)
你可以从下面的代码开始,稍微调整一下(你对第一周的定义是什么:第一周或第一周)。此外,您还必须处理第一周和上周的特殊情况。
int const year = 2012;
int const week = 24;
boost::gregorian::greg_weekday const firstDayOfWeek = boost::gregorian::Monday;
boost::gregorian::date const jan1st(year, boost::gregorian::Jan, 1);
boost::gregorian::first_day_of_the_week_after const firstDay2ndWeek(firstDayOfWeek);
boost::gregorian::date const begin2ndWeek = firstDay2ndWeek.get_date(jan1st);
boost::gregorian::date const end2ndWeek = begin2ndWeek + boost::gregorian::days(6);
boost::gregorian::date const beginNthWeek = begin2ndWeek + boost::gregorian::weeks(week - 2);
boost::gregorian::date const endNthWeek = end2ndWeek + boost::gregorian::weeks(week - 2);
std::cout << boost::gregorian::to_iso_extended_string(jan1st) << std::endl;
std::cout << boost::gregorian::to_iso_extended_string(begin2ndWeek) << std::endl;
std::cout << boost::gregorian::to_iso_extended_string(end2ndWeek) << std::endl;
std::cout << boost::gregorian::to_iso_extended_string(beginNthWeek) << std::endl;
std::cout << boost::gregorian::to_iso_extended_string(endNthWeek) << std::endl;
为了帮助别人,我想回答我自己的问题如下:
COleDateTime YearWeekDayToCalendarDate(int nYear, int nWeekNumber, int nWeekDay)
{
// This method requires that one know the weekday of 4 January of the year in question
int nFirstWeekDay = WeekDay(nYear, 1, 4);
// Add 3 to the number of this weekday, giving a correction to be used for dates within this year
int nDaysOffset = nFirstWeekDay + 3;
// Multiply the week number by 7, then add the weekday.
int nOrdinalDayNumber = (nWeekNumber * 7) + nWeekDay;
// From this sum subtract the correction for the year.
nOrdinalDayNumber = nOrdinalDayNumber - nDaysOffset;
// If the ordinal date thus obtained is zero or negative, the date belongs to the previous calendar year;
if (nOrdinalDayNumber <= 0)
nYear--;
int nTotalDaysInTheYear = 365;
if ( LeapYear(nYear) )
nTotalDaysInTheYear++;
// If greater than the number of days in the year, to the following year.
if (nOrdinalDayNumber > nTotalDaysInTheYear)
nYear++;
// The result is the ordinal date, which can be converted into a calendar date using the following function
unsigned int nMonth, nDay;
YearDayToMonthDay(nOrdinalDayNumber, nYear, nDay, nMonth);
COleDateTime dtCalendar(nYear, nMonth, nDay, 0, 0, 0);
return dtCalendar;
}
int WeekDay(int nYear, int nMonth, int nDay)
{
// Find the DayOfYearNumber for the specified nYear, nMonth, and nDay
const int AccumulateDaysToMonth [] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
// Set DayofYear Number for nYear, nMonth, and nDay
int nDayOfYearNumber = nDay + AccumulateDaysToMonth[nMonth - 1];
// Increase of Dayof Year Number by 1, if year is leapyear and month greater than February
//if ( LeapYear(nYear) && (nMonth == 2) )
if ( LeapYear(nYear) && (nMonth > 2) )
nDayOfYearNumber += 1;
// Find the Jan1Weekday for nYear (Monday = 1, Sunday = 7)
int i, j, k, l, nJan1Weekday, nWeekday;
i = (nYear - 1) % 100;
j = (nYear - 1) - i;
k = i + i / 4;
nJan1Weekday = 1 + (((((j / 100) % 4) * 5) + k) % 7);
// Calcuate the WeekDay for the given date
l = nDayOfYearNumber + (nJan1Weekday - 1);
nWeekday = 1 + ((l - 1) % 7);
return nWeekday;
}
void YearDayToMonthDay(unsigned int nYearDay, unsigned int nYear,
unsigned int& nMonthDay, unsigned int& nMonth)
{
// Day is the day between 1 and 366
// Year is the year you wish
unsigned int nMonthTable[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
unsigned int nMonthDays = 0;
if ((nYear % 4 == 0) && ((!(nYear % 100 == 0)) || (nYear % 400 == 0)))
nMonthTable[1] = 29;
else
nMonthTable[1] = 28;
nMonth = 0;
while (nYearDay > nMonthDays)
nMonthDays += nMonthTable[nMonth++];
nMonthDay = nYearDay - nMonthDays + nMonthTable[nMonth - 1];
}
inline bool LeapYear( int nYear )
{
// Find if nYear is LeapYear
if ( (nYear % 4 == 0 && nYear % 100 != 0) || nYear % 400 == 0)
return true;
else
return false;
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 当回溯以零开始时,如何调试崩溃
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 如何使用 C 连续输出自计算开始以来的秒数
- 根据给定的年份和周数计算开始和结束日期/时间
- OPENCV :从图像左边缘开始计算像素
- 从日期开始计算一年中的某一天
- 从午夜开始计算毫秒数
- C++函数,从double开始进行基数为10的有效+指数计算