首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++创建日期计算器

用C++创建日期计算器
EN

Stack Overflow用户
提问于 2017-06-13 00:01:55
回答 3查看 398关注 0票数 1

我需要用C语言创建一个基本的日期计算器,让用户输入YYYY-MM-DD格式的日期。我把它的基本知识写下来了。虽然我不需要这样做,但我想要多做一点,并考虑到闰年的因素。该程序运行良好;但是,它不能正确地计算闰年。当我输入日期2016-02-26时,我应该得到一个预期的结果2016-03-04,但我得到的结果是2016-03-03。我估计,如果我使用if else语句,效果就像下面使用模数一样。

代码语言:javascript
复制
if (month == 2 && year % 4) days = 29; 
   else days = 28;

这是我的完整代码..。

代码语言:javascript
复制
//Does not require <stdlib.h>
#include <stdio.h>

// Set variables
int newDay, newMonth, newYear, daysInMonth, daysRemain;
// Set structure for day month year
struct date {
    int day, month, year;
};
// set structure for date
struct date d1;

int main (void) {
    //Intro
    printf("Date calculation program by Keith A. Russell");
    //Asks for user input
    printf("\n\nPlease enter the year in four digit format (YYYY) ");
    scanf("%i", &d1.year);
    printf("\nEnter the month in two digit format (MM) ");
    scanf("%i", &d1.month);
    printf("\nEnter the day in two digit format (DD) ");
    scanf("%i", &d1.day);
    //Runs calculations to increase the date by a week
    newDay = d1.day + 7;
    newMonth = d1.month;
    newYear = d1.year;
    daysRemain = 0;
    //For if the next week is going to be greater than the next month
    if (newDay > 28)
        checkMonth();  //Runs checkMonth Function
    //Prints the dates
    printf("\nThe new date is %i-%i-%i: \n", newYear, newMonth, newDay);
}

checkMonth() {
    if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
        daysInMonth = 31;               //For months with 31 days
    if (d1.month == 2 && d1.year % 4)   //Attempt to calculate leap year
        daysInMonth = 29;
    else {
        daysInMonth = 28;           //All other years
    }
    if (d1.month == 4 || 6 || 9 || 11)  //For months with 30 days
        daysInMonth = 30;
    //Sets up to advance the year if approaching the end of year
    if (newDay > daysInMonth) {
        daysRemain = newDay - daysInMonth;
        newDay = daysRemain;
        newMonth++;
        checkYear();
    }
}
//Runs function to advance to the next year
checkYear() {
    if (d1.month == 12)
        if (daysRemain > 0) {
            newYear++;
            newMonth = 1;
        }
}

如果有更好的方法来计算闰年,并将其包含在这个程序中,我将非常感谢。谢谢。

EN

回答 3

Stack Overflow用户

发布于 2017-06-13 00:05:57

首先,这是错误的

代码语言:javascript
复制
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)

这将永远是正确的。你需要

代码语言:javascript
复制
if (d1.month == 1 || d1.month == 3 || d1.month == 5 ....)
票数 2
EN

Stack Overflow用户

发布于 2017-06-13 00:10:34

这并不是你所想的那样:

代码语言:javascript
复制
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)

您不能像这样将一个值与一系列值进行比较。你实际做的是这样的:

代码语言:javascript
复制
if ((d1.month == 1) || 3 || 5 || 7 || 8 || 10 || 12)

您正在将d1.month与值1进行比较,然后将该布尔结果与其他几个数字进行逻辑或。由于所有这些数字都不为零,因此此表达式的计算结果始终为true。

这一点也是如此:

代码语言:javascript
复制
if (d1.month == 4 || 6 || 9 || 11)

您需要显式地比较每个值:

代码语言:javascript
复制
if ((d1.month == 1) || (d1.month == 3) || (d1.month == 5) ...

实际上,您可以使用带有fallthrough cases的switch更干净利落地完成此操作:

代码语言:javascript
复制
switch (d1.month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
    daysInMonth = 31;
    break;
case 4:
case 6:
case 9:
case 11:
    daysInMonth = 30;
    break;
case 2:
    // years divisible by 100 are not leap years, unless they are also divisible by 400
    daysInMonth = (d1.year % 400 == 0) ? 29 :
                  (d1.year % 100 == 0) ? 28 :
                  (d1.year % 4 == 0) ? 29 : 28;
    break;
}
票数 2
EN

Stack Overflow用户

发布于 2017-06-13 04:42:51

您的代码中存在多个问题:

  • 闰年的测试是不正确的:(d1.month == 2 && d1.year % 4)表示1901年和2099年之间的正常年份,这不是闰年。正确的测试是这样的:

if (d1.month == 2 && (d1.year % 4) == 0) //尝试计算闰年daysInMonth = 29;

但是请注意,根据公历改革后的历法,100的年份的倍数如果不是400的倍数也不是闰年,那么完整的测试是这样的:

如果(d1.month == 2) { daysInMonth = (d1.year %4 || (!(d1.year % 100) && (d1.year % 400))?28 : 29;}

  • 您的月值测试不正确:代替if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12),您应该这样写:

if (d1.month == 1 || d1.month == 3 || d1.month == 5 || d1.month == 7 || d1.month == 8 || d1.month == 10 || d1.month == 12)

要使代码更具可读性,可以使用switch语句。如果您首先检查d1.month在1到12之间,则可以将上述测试压缩为更紧凑的单个测试:

代码语言:javascript
复制
if ((1 << d1.month) & ((1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 8) | (1 << 10) | (1 << 12))) {
    daysInMonth = 31;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44503883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档