我正在写一个简单的日历课程。我正在尝试重载操作员
,以便使用它将日历移动到下个月。然而,我找到下个月开始日期的算法并不完全正确。
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;
}
1月定义为0,12月为11,周日为0,周六为6。start Day、previousStartDay、nextStartDay、月份和年份都是私有类变量
当我在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;
我认为问题在于2月,因为这个月可能有29天或28天(取决于一年是否为双性年)。您可以创建本月的if语句。你可以通过使用mod操作符if:the year%4=(如果:年份%4=)!2月只有28天,而2月只有29天。希望这对你有帮助!
boost给了你几个很好的例子。在这里,我基于示例中的一个实现了boost::gregorian
。此代码记录年份、月份,并打印下个月第一天的日期和星期几:
#include <cstdlib>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>
#include <stdio.h>
int main(int argc, char** argv) {
using namespace boost::gregorian;
greg_year year(1400);
greg_month month(1);
// get a month and a year from the user
try {
int y, m;
std::cout << " Enter Year(ex: 2002): ";
std::cin >> y;
year = greg_year(y);
std::cout << " Enter Month(1..12): ";
std::cin >> m;
month = greg_month(m);
}
catch(bad_year by) {
std::cout << "Invalid Year Entered: " << by.what() << '\n'
<< "Using minimum values for month and year." << std::endl;
}
catch(bad_month bm) {
std::cout << "Invalid Month Entered" << bm.what() << '\n'
<< "Using minimum value for month. " << std::endl;
}
// create date and add one day to the end of month
date d(year, month, 1);
d=(year,month,d.end_of_month());
date_duration dd(1);
d += dd;
// print date
std::cout << d << " " << d.day_of_week() << std::endl;
return 0;
}
输出示例:
输入年份(例如:2002年):2013年
输入月份(1..12):3
2013年4月1日星期一
运行成功(总时间:6s)
使用std::vector
:
boost::gregorian::date d1(2013,boost::gregorian::Jan,31);
boost::gregorian::date d2(2013,boost::gregorian::Feb,28);
boost::gregorian::date d3(2013,boost::gregorian::Mar,31);
std::vector<boost::gregorian::date > v;
v.push_back(d1);
v.push_back(d2);
v.push_back(d3);
boost::gregorian::date_duration duration(1);
for(std::vector<boost::gregorian::date >::iterator it=v.begin();it!=v.end();it++){
*it+=duration;
std::cout << *it <<" "<< (*it).day_of_week() << std::endl;
}
让我们假设我们在三月,你有正确的开始日(星期五,5)。
你的findNextStartDay
算法将发现monthlength
等于3(31-28),那么一天将是2(8-6),也就是周二(2),而不是周一(1)。。。
让我们通过运行算法(findNextStartDay的第一个版本)来了解为什么这是错误的:
1月:31-28=3,第2天(星期二)3=5(星期五),这是2月的正确开始日期。
二月:28-28=0,天=5(星期五)0=5(星期五),这是三月的正确开始日期。
三月:31-28=3,天=5(星期五)3-6(星期六)=2(星期二),这是四月的错误开始日期。
问题是,当你减去星期六导致溢出(超过星期六)时,你在计算中漏掉了一天(即:你比你想要的少减去一天)。
想想你最终得到day==7
的情况。你想有星期天(比星期六多一个-循环增加),然后你必须删除7,而不是6,否则你会得到星期一!
误差在循环增量中:在正确的算法中,超过6的1(即7)必须返回到0,超过6的2(即8)必须返回到1,依此类推。
在你的算法中,超过6的1(即7)返回到1,去掉可怜的0(星期日),并使一周中的一天在每次结束时消失。
如果您减去星期六1
,您将获得下个月的正确日期,以防“星期天溢出”。
简而言之,改变这一行:
day -= Saturday;
到
day -= (Saturday + 1);
但是,请考虑将您的代码审查为更干净的算法版本!
小技巧是使用模运算符进行循环加法:
day = ((day + monthlength) % (Saturday + 1))
我试图在我正在创建的C#应用程序中显示两个日期之间的年、月和日。(使用控制台进行测试) 我正在使用NodaTime来实现这一点,但在接下来的几个月里,我遇到了一些问题。 我已经阅读了这里的大部分问题和答案,但没有找到任何我可以从中受益的东西。 大多数时候函数工作但有时它不添加月如果天 我使用这个代码进行测试 (2017, 10, 16)和(2018, 1, 15)应该显示为3个月,但它们显示为2个
问题内容: 使用date(1970年1月1日)作为时间操纵的默认标准有什么原因吗?我已经在Java和Python中看到了这个标准。我知道这两种语言。还有其他遵循相同标准的流行语言吗? 请描述。 问题答案: 这是Unix时间的标准。 Unix时间或POSIX时间是一种用于描述时间点的系统,时间点定义为自1970年1月1日午夜多点协调世界时(UTC)起经过的秒数,不包括leap秒。
我正在开发一个程序,它采用开始日期和结束日期,并返回年、月和日的不同值。每个类别都有自己的代码部分,这是我一直在使用的代码,到目前为止,它一直是半精确的,直到几天(有时是几个月。我甚至不想在这一点上愚弄闰年) Ex Start:04/10/2000 End:04/10/2006应该给我6年零个月零天。 年份代码: 月份代码: 天数代码:我已经尝试了多个版本,但没有太大的成功,例如,我可以计算天数之
如何在Android中获取和显示日期以来的天数,月份和年份? 例如,假设上一个日期是: 今天的日期是: 我希望它能这样说: 我想我需要得到这样的总天数: 但是我如何将天数转换为年、月和天呢?请记住,并不是所有的月都有31天。 因为这样我只会 结果呢。但我希望它更像是1年2个月28天。 有更好的解决方案吗? 我也想得到像这样的旧日期在一个变量: 但是上面的代码根本不起作用。是的,我知道变量在kotl
问题内容: 我有两个约会: 开始日期: 结束日期: 在上述两个日期之间的91天持续时间,我希望我的代码返回3个月的持续时间,但以下方法仅返回2个月。有谁有更好的建议?还是你们认为这是Java 8中的错误?工期为91天,仅返回2个月。 非常感谢你的帮助。 方法1: 方法2: 方法3: 我尝试使用Joda库而不是Java 8 API,它可以工作。它会返回3,它看起来像Java持续时间月份的计算也使用了
问题内容: 如果不使用PHP 5.3的date_diff函数(我使用的是PHP 5.2.17),是否有一种简单而准确的方法?我正在考虑以下代码,但是我不知道如何计算leap年: 我正在尝试计算一个人的月数。 问题答案: 您可能还希望将某天包括在内,具体取决于您是否指的是 整个 月。希望你能明白。