下面总结了一些有关日期计算的一些问法以及应对方式
1.平闰年的判断:众所周知即为,(year%4 ==0&&year%100!=0)||(year%400==0)
由于程序中经常用到此函数,不妨写一个函数用来判断:
int isLeapYear(int y){
if((y%4==0&&y%100!=0)||(y%400==0))
return 1;
return 0;
}
这里用int返回类型,可以作为返回值直接使用
2.利用事先写好的平闰年的日期数组:
int data[][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
通过isLeapYear的返回值即可访问对应的那一行
问题一:如问当前输入的日期是今年的第几天,属于正向问题求解,思路主要是通过遍历data数组,将天数累加最后加上所输入日期的天数即可:
int month=1;
int t = isLeapYear(y); //用于访问data对应的行
int i =0;
while(n>=data[t][i]){
n = n - data[t][i];
i++;
}
month = i+1; //月份要比数组的下标多1
这里对于日期的格式化输入做一个小的笔记:
例如当题目是按照 2008-08-26 格式输入时,我们此时如何把“ - ”过滤掉,只保存年月日呢?
这里使用c语言的scanf的格式化输入: #include<stdio.h>头文件
scanf("%d-%d-%d",&y,&m,&d); //格式化输入 如 2008-08-26
问题二:问题一的反问题,即求输入一个年份和一个天数,问对应的日期,反向求解即可。通过number天数遍历data数组,每次用 number -=data[t][month],并且使month+1,最后剩余的number即为该日期的天数(day)这一项
注意这里有一个格式化输出的问题,是与上题问题相对应的。也是使用c语言标准库中的输出函数 printf
printf("%04d-%02d-%02d\n",y,m,d); //例如2008-08-26
注意这里有一个“不足就要补位”的概念,当输出的场宽不足时,即通过补上0 :%04d就是场宽为4 不足补0
问题三:日期累加:设计一个成语,实现计算一个日期加上若干天后是什么日期。此问题是在上两个问题的基础上,增加了对年份的计算,因为加上的若干天可能会出现超过该年的情况,因此要将所输入的日期的天数保存下来+若干天,用整年的天数与其相比较,将年份做相应的变动。再对剩余天数进行上述问题二的类似求解,得到对应的月份和天数。
设置一个返回某年份天数的函数:
int NumberofYear(int y){
if(isLeapYear(y)) return 366;
return 365;
}
#include<bits/stdc++.h>
using namespace std;
int isLeapYear(int y){ //判断平闰年
if((y%4==0&&y%100!=0)||(y%400==0))
return 1;
return 0;
}
int NumberofYear(int y){
//获得年份对应的天数
if(isLeapYear(y)) return 366;
return 365;
}
int main(){
int data[][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
int n,y,m,d,x;
cin>>n;
while(n--){
cin>>y>>m>>d>>x;
//先计算当前日期为该年的哪一天
int number = d;
int t = isLeapYear(y);
for(int i=0;i<m-1;i++){
number += data[t][i];
}
number += x;
//得到累加天数后的新年份
while(number>NumberofYear(y)){
number -= NumberofYear(y);
y++;
}
//得到累加天数后的新月份
m =0;
t = isLeapYear(y);
while(number>data[t][m]){
number -= data[t][m];
m++;
}
//得到累加天数后的新天数
d = number;
printf("%04d-%02d-%02d\n",y,m+1,d);
}
}