有关日期年月日相关计算的问题汇总

下面总结了一些有关日期计算的一些问法以及应对方式

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值