C++ 根据给定的年和周数计算开始和结束日期/时间

C++ 根据给定的年和周数计算开始和结束日期/时间,c++,datetime,C++,Datetime,如何计算给定年份的开始和结束日期/时间(YYYY-mm-DD HH:mm::SS)以及该年份的ISO周数 在再次问这种问题之前,我搜索了一下。当然,有一些线程涉及从(年、周数)到(日期时间)的转换。但是,他们通过Perl、PHP、java、SQL、C++、.NET、Excel和其他编程语言来回答,除了C/C++之外, < P>恐怕没有简单的解决这个问题的方法。然而,编写解决方案并不难。你只需要处理一些特殊情况(比如第一周和最后一周,二月,闰年)。一种方法可以是 从一年的周数中,获取该年的日数(即

如何计算给定年份的开始和结束日期/时间(YYYY-mm-DD HH:mm::SS)以及该年份的ISO周数


在再次问这种问题之前,我搜索了一下。当然,有一些线程涉及从(年、周数)到(日期时间)的转换。但是,他们通过Perl、PHP、java、SQL、C++、.NET、Excel和其他编程语言来回答,除了C/C++之外,

< P>恐怕没有简单的解决这个问题的方法。然而,编写解决方案并不难。你只需要处理一些特殊情况(比如第一周和最后一周,二月,闰年)。一种方法可以是

  • 从一年的周数中,获取该年的
    日数
    (即开始和结束日数)。(注意这里的第一周和最后一周)
  • 现在,使用
    日数
    就可以很容易地找到月份和日期。(注意这里的二月)

  • 您可以从下面的代码开始,对其进行一些调整(您对第一周的定义是什么:第一整周还是第一部分周)。你还必须处理第一周和最后一周的特殊情况

      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;
    
    int const year=2012;
    int const周=24;
    boost::gregorian::greg_weekday const firstDayOfWeek=boost::gregorian::Monday;
    boost::gregorian::日期常量1月1日(年份,boost::gregorian::1月1日);
    boost::gregorian::const firstDay2ndWeek(firstDayOfWeek)后一周的第一天;
    boost::gregorian::date const begin2ndWeek=firstDay2ndWeek.get_date(1月1日);
    boost::gregorian::date const end2ndWeek=begin2ndWeek+boost::gregorian::days(6);
    boost::gregorian::date const beginNthWeek=begin2ndWeek+boost::gregorian::weeks(第2周);
    boost::gregorian::date const endNthWeek=end2ndWeek+boost::gregorian::weeks(第2周);
    
    为了帮助别人,我想回答我自己的问题如下:

    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;
    }
    
    COleDateTime yearkdaytocalendardate(int nYear,int nWeekNumber,int nWeekDay)
    {   
    //这种方法要求知道一年中1月4日的工作日
    int nFirstWeekDay=工作日(nYear,1,4);
    //在该工作日的数字上添加3,对今年内的日期进行更正
    int nDaysOffset=nFirstWeekDay+3;
    //将周数乘以7,然后将工作日相加。
    int nOrdinalDayNumber=(nWeekNumber*7)+nWeekDay;
    //从这个总数中减去当年的修正数。
    nOrdinalDayNumber=nOrdinalDayNumber-nDaysOffset;
    //如果由此获得的序号为零或负值,则该日期属于上一日历年;
    如果(nOrdinalDayNumber NTOTALDAYIN THEAR)
    nYear++;
    //结果是序号日期,可以使用以下函数将其转换为日历日期
    无符号整数n月,星期日;
    YearDayTomenthday(nOrdinalDayNumber,nYear,nDay,nMonth);
    COleDateTime dtCalendar(nYear、nMonth、nDay、0、0);
    返回日历;
    }
    国际工作日(国际纽约、国际纽约、国际星期日)
    {   
    //查找指定nYear、nMonth和nDay的DayOfNumber
    const int acgregatedaystomonth[]={0,31,59,90,120,151,181,212,243,273,304,334};
    //设置nYear、nMonth和nDay的DayofYear编号
    int NdayOfyEnumber=nDay+累计系统数[nMonth-1];
    //如果年和月大于2月,则将年的天数增加1
    //如果(闰年(nYear)和&(nMonth==2))
    如果(闰年(nYear)和&(nMonth>2))
    ndayofyEnumber+=1;
    //查找nYear的1月1日工作日(周一=1,周日=7)
    int i、j、k、l、NJAN1工作日、N工作日;
    i=(nYear-1)%100;
    j=(nYear-1)-i;
    k=i+i/4;
    Njan1工作日=1+(((((j/100)%4)*5)+k)%7);
    //计算给定日期的工作日
    l=NdayofyEnumber+(Njan1工作日-1);
    nWeekday=1+((l-1)%7);
    逢星期一返回;
    }
    无效的YearDayTomentDay(未签名的整数nYearDay,未签名的整数nYear,
    无符号整数和无符号整数(第天,无符号整数和无符号整数)
    {   
    //Day是介于1和366之间的一天
    //年就是你希望的一年
    无符号int-nMonthTable[12]={31,28,31,30,31,30,31,31,30,31,30,30,31};
    无符号整数nMonthDays=0;
    如果((nYear%4==0)和(!(nYear%100==0))| |(nYear%400==0)))
    nMonthTable[1]=29;
    其他的
    nMonthTable[1]=28;
    nMonth=0;
    而(nYearDay>nMonthDays)
    nMonthDays+=nMonthTable[nMonth++];
    nMonthDay=nYearDay-nmonthdies+nMonthTable[nMonth-1];
    }
    内联布尔跳跃年(内联)
    {  
    //查找nYear是否是LeapYear
    如果((nYear%4==0&&nYear%100!=0)| | nYear%400==0)
    返回true;
    其他的
    返回false;
    }
    
    因此,这里不是获取编程任务逐字解决方案的地方。感谢您的建议!我会设法弄明白的。