c ++中具有闰日的日期算法

时间:2014-02-04 00:31:08

标签: c++ date loops if-statement

我正在尝试让用户选择要添加到2014年1月1日的特定日期。 我做得很成功,我做了所有的计算。但是,当我在2014年1月1日添加60天时。我得到3/0/2014。我试图通过改变日子来避免这种情况,但这种情况并不奏效。另外,如果我加了800000天,我会超过12个月,这也不可能是真的。 我试着通过做一些像月> = 12的开头的if语句来避免这种情况。但是,不应该是这种情况,否则如果我选择添加80000000天,它将永远是12月。另外,我不知道在这种情况下我应该如何处理闰年,因为无论何时我在年度增量之前添加if语句都会回到2014年。当我尝试在月之前使用if语句时也会发生这种情况增量。

这是我到目前为止所做的:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

class Date
{
public:
    int day, year, monthnum;
    Date operator+(const Date&);
};

Date Date:: operator+(const Date& date)
{
    cout << "Enter a day" << endl;
    cin >> day;
    if(day>=1)
    {
    while(day<=30 && monthnum ==1 || day<=30 && monthnum ==3 || day<=30 && monthnum ==7 || day<= 30 && monthnum ==8 || day<=30 && monthnum == 10 || day<=30 && monthnum == 12)
    {
        return Date(date.day+day,date.monthnum ,date.year); 
    }

    while(day<=29 && monthnum ==9 || day<=29 && monthnum == 4 || day<=29 && monthnum == 6 || day<= 29 && monthnum == 11)
    {
        return Date(date.day+day,date.monthnum ,date.year);
    }
    while(day>=364)
    {
        day =day - 364;
        year++;
    }
    while(day>29 && monthnum ==9 || day>29 && monthnum == 4 || day>29 && monthnum == 6 || day>29 && monthnum == 11)
    {
        while(day>=29)
        {
        day = day -29;
        monthnum ++;
        }
    }
    while(day>30 && monthnum ==1 || day>30 && monthnum ==3 || day>30 && monthnum ==7 || day>30 && monthnum ==8 || day>0 && monthnum == 10 || day>30 && monthnum == 12)
    {
        while(day>=30)
        {
        day = day -30;
        monthnum ++;    
        }
    }
    }
    else
    {
        cout << "Day should be greater than 0 !";
    }
}

有人可以帮我解决这个问题吗?或者至少为我提供逻辑? 提前致谢

3 个答案:

答案 0 :(得分:2)

我编辑了我的答案以提供我使用的代码,以及相对于最初提供的代码的更改注释。

下面的完整(工作)代码:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

class Date
{
public:
    int day, year, monthnum;
    void operator+(int day);
    bool leapYear;
    void print_date()
    {
        std::cout << "The date after addition is: ";
        std::cout << (this->day +1) << "/" << (this->monthnum +1) << "/" << (this->year) << std::endl;
        // Year probably doesn't require a +1, but you can check.
    }
    int daysInMonth[12];
    void set_daysInMonth()
    {
        // This is a mess, and most of these are constant, and so don't need to be a part of this function.
        // Really, you need a set_daysInFeb() function, but you also need to set the values for the other
        // months at least once, so I just put them here.
        daysInMonth[0]=31;
        daysInMonth[2]=31;
        daysInMonth[4]=31;
        daysInMonth[6]=31;
        daysInMonth[7]=31;
        daysInMonth[9]=31;
        daysInMonth[11]=31;
        daysInMonth[3]=30;
        daysInMonth[5]=30;
        daysInMonth[8]=30;
        daysInMonth[10]=30;
        if (leapYear) { daysInMonth[1]=29;}
        else {daysInMonth[1]=28;}
    }
};

void Date:: operator+(int day_var)
{
    if(day_var>=1)
    {
            day_var += day;
        while(day_var>365)
        {
            if (year%4==0 && year%1000 !=0)
            {
                leapYear = true;
                if (day_var > 366)
                {
                    day_var = day_var-366;
                    year++;
                }
            }
            else
            {
                leapYear = false;
                day_var = day_var-365;
                year++;
            }
        }

        set_daysInMonth();
        while (1)
        {
            if (day_var < daysInMonth[monthnum])
            {break;}
            day_var = day_var - daysInMonth[monthnum];
            monthnum ++;
            if (monthnum == 12)
            {
                year++;
                monthnum = 0;
                set_daysInMonth(); // This requires you to move some code around,
                // since it doesn't update the values in the right places.
            }
        }

        day = day_var;  // note that this is assigning remaining days (day_var)
                            // to the Date date_var.day variable    
    }
    else
    {
        cout << "Day should be greater than 0 !";
    }
}

int main()
{
    int day=0;
    cout << "Enter a day" << endl;
    cin >> day;
    Date date_var;
    date_var.year = 2014;
    date_var.monthnum = 1;
    date_var.day = 3;
    date_var + day;
    date_var.print_date();
    return 0;
}

最初,您需要从cin >> day;运算符中删除+,然后将其放在main()函数中。

我实施了属于您print_date()的{​​{1}}功能,以便您可以轻松显示课程中的日期。

我使class Date运算符成为void运算符。这可能不是一个很好的计划,可能值得改变,但是如何确定如何返回一个合适的类对象似乎更加努力。您可以尝试+或类似的东西。

我添加了一个return this;函数,允许您实例化一个月中包含天数的数组,并在2月更改闰年的天数。如果输入的天数导致年份进入闰年,则可能无法正常运行 - 您应该检查并调整一些函数调用以便正确检查年份,设置2月份的天数(void set_daysInMonth())然后检查循环。

daysInMonth[1]循环用于减少while(1)中的天数,直到它低于预期月份的天数,此时将触发day_var

Date类没有构造函数,因此在break函数中创建并赋值。您可以考虑编写两个构造函数,一个包含三个int参数,另一个空白,允许您编写main()Date new_date(day, month, year);等。

祝你想做出任何改变,祝你好运:)

答案 1 :(得分:1)

有一种更简单的方法可以做到这一点。查看Julian Date calculation。这个想法是Julian日期值在整数空间上是连续的和密集的。因此,您可以将日期转换为Julian格式,将偏移量添加为天数,然后将其转换回来以获取远离原始日期的日期。

答案 2 :(得分:0)

我不确定实施是否正确,但对我来说,你似乎在混合几天和几个月。由于看起来你只输入几天作为输入,我只会使用几天,因为一个月不是一个固定的数字。我无法确切地告诉你几个月和几天要做什么以及减去。

首先,如果您计算一年超过365天并减去365天。 我认为最明确的方法是每年给每个月的每一天。也就是说,第1天到第31天是1月,第32天到第59天是2月等等。然后,一旦你有月减去一个月前一年的天数,所以第33天将是2月和33- 31 =第二天。

此外,我确信C ++有一些日期和计数库。