c++ - 计算下个月开始日期的算法

标签 c++ time calendar

我正在编写一个简单的日历类。我正在尝试重载 operator++ 以使用它将日历移动到下个月。但是,我查找下个月开始日期的算法不太正确。

calendar calendar::operator ++(int)
{
   int hold;
   calendar cal = *this;

   month++;
   if (month > December)
   {
      month = January;
      year++;
      if (year == 0)
         year++;
   }
   previousStartDay = startDay;
   startDay = nextStartDay;
   nextStartDay = findNextStartDay();
   return cal;
}

int calendar::findNextStartDay() const
{
   int monthLength,
       day = startDay;

   monthLength = findMonthLength(false);
   monthLength -= 28;
   day += monthLength;
   if (day > Saturday)
      day -= Saturday;
   return day;
}

January定义为0,December为11,Sunday为0,Saturday为6。startDay,previousStartDay,nextStartDay,month,year都是私有(private)类变量

当我针对 2013 年对此进行测试时,日期在 3 月之前都是正确的。此时它将下一个开始日指定为星期二而不是星期一。

我也试过这个:

int calendar::findNextStartDay() const
{
   int monthLength,
       day = startDay;

   monthLength = findMonthLength(false);
   monthLength -= 28;
   day -= monthLength;
   if (day < Sunday)
      day += Saturday;
   return day;
}

然而,它也给出了相同的结果。

编辑:

我计算的是闰年。这是我来自 findMonthLength() 的代码,用于确定它是否存在。

if ((!(year % 4) && (year % 100)) || !(year % 400))
   monthLength = 29;
else
   monthLength = 28;

最佳答案

问题分析

假设现在是三月,而您的开始日期是正确的(星期五,5)。

您的 findNextStartDay 算法会发现 monthlength 等于 3 (31-28),那么日期将为 2 (8 - 6),即星期二 (2)星期一 (1)...

让我们通过运行算法(findNextStartDay 的第一个版本)看看为什么这是错误的:

一月:31-28 = 3,day = 2(星期二)+ 3 = 5(星期五),这是二月的正确开始日期。

2 月:28 - 28 = 0,day = 5(星期五)+ 0 = 5(星期五),这是三月的正确开始日期。

3 月:31-28 = 3,day = 5(星期五)+ 3 - 6(星期六)= 2(星期二),这是错误的 4 月开始日期。

错误解释

问题是,当您减去星期六导致溢出(多于星期六)时,您会少算一天(即:您减去的天数比您想要的少一天)。

想想你以 day == 7 结束的情况。你会想要星期天(比星期六多一个 - 循环增加),然后你必须删除 7,而不是 6,否则你将得到星期一!

错误在于循环增量:在正确的算法中,1 超过 6(即 7)必须回到 0,2 超过 6(即 8)必须回到 1,依此类推。

在您的算法中,超出 6(即 7)的 1 返回到 1,而忽略了可怜的 0(星期日),并且每次您以这种情况结束时,都会使一周中的某一天消失。

如果您减去 Saturday + 1,您将得到下个月的正确日期,以防“工作日溢出”。

错误修复

简而言之,改变这一行:

day -= Saturday;

day -= (Saturday + 1);

但是请考虑检查您的代码以获得更清晰的算法版本!

一个小技巧是使用模运算符进行循环加法:

day = ((day + monthlength) % (Saturday + 1))

关于c++ - 计算下个月开始日期的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16346721/

相关文章:

javascript - Lerp 背景颜色基于一天中的时间

css - 第 n 列的换行行仅对日历或图片库使用 CSS

java - HH 日期时间格式问题

c++ - 如何将右值引用参数传递给 C++ 中的模板 operator() 函数?

c++ - 是否可以在运行时修改可执行文件?

php - Unix 时间戳和 JavaScript 时间;太大!

python - 看不懂这个定时while循环属性报错

c++ - Visual Studio 中的多项目解决方案 : spread the config of the main project

c++ - C 中的结构

api - Office 365 日历休息 API : Meeting Vs. 预约