我需要在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;
}
}
如果有更优雅的方法来计算闰年并将其包含在此计划中,我会非常感激。谢谢。
答案 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;
}