在C中创建日期计算器

时间:2017-06-12 16:01:55

标签: c

我需要在C中创建一个基本日期计算器,让用户输入YYYY-MM-DD格式的日期。我有它的基础知识。虽然我不需要,但是我想在闰年上花一点点时间。该计划运行良好;但是,它并没有正确计算闰年。当我输入2016-02-26的日期时,我应该得到2016-03-04的预期结果,但我得到2016-03-03的结果。我估计如果我使用if else语句来使用modulo来实现以下效果。

if (month == 2 && year % 4) days = 29; 
   else days = 28;

这是我的完整代码......

//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;
        }
}

如果有更优雅的方法来计算闰年并将其包含在此计划中,我会非常感激。谢谢。

3 个答案:

答案 0 :(得分:2)

一开始这是错误的

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

永远都是如此。你需要

if (d1.month == 1 || d1.month == 3 || d1.month == 5 ....)

答案 1 :(得分:2)

这不符合你的想法:

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

您无法将一个值与这样的值列表进行比较。你实际在做的是:

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

您将d1.month与值1进行比较,但随后您获取该布尔结果并与其他几个数字进行逻辑或运算。由于所有这些数字都不为零,因此该表达式将始终评估为真。

同样如此:

if (d1.month == 4 || 6 || 9 || 11)

您需要明确地与每个值进行比较:

if ((d1.month == 1) || (d1.month == 3) || (d1.month == 5) ...

您可以使用switch更简洁地执行此操作:

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 :(得分:1)

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

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

    if (d1.month == 2 && (d1.year % 4) == 0)   //Attempt to calculate leap year
        daysInMonth = 29;
    

    但是请注意,根据格里高利改革日历,100年的倍数不是400的倍数不是闰年,所以完整的测试是这样的:

    if (d1.month == 2) {
        daysInMonth = (d1.year % 4 || (!(d1.year % 100) && (d1.year % 400)) ? 28 : 29;
    }
    
  • 您对月份值的测试不正确:您应该写下:{/ p>而不是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之间,您可以将上述测试浓缩为更紧凑的单一测试:

if ((1 << d1.month) & ((1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 8) | (1 << 10) | (1 << 12))) {
    daysInMonth = 31;
}