日期处理


  日期处理的问题,一般会需要处理平年和闰年(二月天数区别)、大月和小月的问题。

举例

日期差值

有两个日期,求两个日期之间的天数,如果两个日期是连续的,则规定它们之间的天数为两天。
输入格式:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD。
输出格式:
每组数据输出一行,即日期差值
样例输入:
20130101
20130105
样例输出:
5

思路:
  不妨假设第一个日期早于第二个日期(否则就交换位置)。
  这样求日期之间相差天数,就可以用第一个日期不断加1天,直到第一个日期=第二个日期为止,即可统计出答案。如果当前d+1之后天数d = 当前月份m所拥有的天数+1,那么就令月份m+1、同时置天数d = 1号(即把日期变为下一个月的1号);如果此时月份m= 13,那么就令年份y+1、同时置月份m = 1月(即把日期变为下一年的1月)。
  为了方便直接取出每个月的天数,不妨给定一个二维数组int month[13][2],用来存放每个月的天数,其中第二维为0时表示平年,第二维为1时表示闰年。
  如果要加快速度,只需要先把第一个日期的年份不断+1,直到与第二个日期的年份相差1为止(不能相等,不然可能第一个日期的月和日>第二个日期),期间根据平年或是闰年来累加365天或者366天即可。之后再进行上述的+1操作。

判断闰年:

bool isLeap(int year){
	if((year % 4 ==0 && year % 100!= 0) || year %400 == 0){
		return true;
	}else{
		return false;
	}
}
#include<bits/stdc++.h>
using namespace std;
int month[13][2] = {{0,0},{31,31},{28,29},{31,31},{30,30},
		{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},
		{30,30},{31,31}};
bool isLeap(int year){
	if((year % 4 ==0 && year % 100!= 0) || year %400 == 0){
		return true;
	}else{
		return false;
	}
}
int main(){
	int time1,y1,m1,d1;
	int time2,y2,m2,d2;
	while(scanf("%d %d",&time1,&time2)!=EOF){
		if(time1>time2){
			int temp = time1;
			time1 = time2;
			time2 = temp;
		}
		y1 = time1 / 10000, m1 = time1%10000/100, d1 = time1%100;
		y2 = time2 / 10000, m2 = time2%10000/100, d2 = time2%100;
		int ans = 1;
		//循环,如果time1不等于time2
		while(y1<y2 || m1<m2 ||d1<d2){
			d1++;//天数+1
			if(d1 == month[m1][isLeap(y1)]+1){//当前月份天数已满 
				m1++;
				d1 = 1;
			}
			if(m1 == 13){ //当前年份月数已满 
				y1++;
				m1 = 1;
			}
			ans++;
		}
		printf("%d\n",ans); 
	}
	return 0;
}

星期几

题目中给出日期,计算出是星期几。
输入格式:
21 December 2012
输出格式:
Friday

思路:
以0000年1月1日为原点,计算给定日期到原点的天数,
再计算今天到原点的天数,两者相减的给定日期和今天的差值,
利用模运算计算周几,注意模运算时不能出现负数利用 (day % 7 + 7) % 7防止出现负数。

#include<stdio.h>
#include<string.h>

int d1, y1, m1;
bool isLeap(int y){
	if(y%400 ==0 ||(y%4 ==0 && y%100 !=0)){
		return true;
	}else{
		return false;
	}
}
int day_of_month[13][2]={
				{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},
				{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},
				{31,31}
				};
char week_name[7][20]={"Sunday", "Monday", "Tuesday", "Wednesday",
                         "Thursday", "Friday", "Saturday"};
char month_name[13][20]={"","January","February","March","April",
				"May","June","July","August","September","October",
				"November","December"};
int date_map[4001][13][32];
int main(){
	int y2 = 0, m2 = 1, d2 = 1, cnt = 0;
    // 打表,计算出2030年之前每个日期与0000年1月1日的距离 
    while (y2 != 2030)
    {
        date_map[y2][m2][d2] = cnt;
        d2++;
        if (day_of_month[m2][isLeap(y2)] + 1 == d2)
            m2++, d2 = 1;
        if (m2 == 13)
            y2++, m2 = 1;
        cnt++;
    }
    
    char m1_str[20];
    while (scanf("%d %s %d", &d1, m1_str, &y1) != EOF)
    {
        m1 = 1;
        for (int i = 1; i < 13; i++)
        {
            if (strcmp(m1_str, month_name[i]) == 0)
                break; //此时m1为当前英文对应的月份 
            m1++;
        }
        int distance = date_map[y1][m1][d1] - date_map[2020][1][1];//选定某一天的日期,计算两者之差
        distance += 3; //2020.1.1为星期三 
         // 数论技巧,防止取余出现负数
         //再对7取余
        int day_of_week = (distance % 7 + 7) % 7;
        printf("%s\n", week_name[day_of_week]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值