日期与天数互转的实现代码(VS2022 C++)

日期是公历日期,即某年某月某日;天数指的是公历纪年的天数,即公元元年(1年)1月1日作为第一天,其他天数依次类推。

在Win10系统中使用VS2022的C++实现。

在VS2022中创建空项目,添加文件“main.cpp”,并输入如下代码:

#include <iostream>
#include <math.h>

//	一个100年(非第四个100年)包含的天数 24个闰年76个平年
#define _100_years_day_ (24*366+76*365)
//	一个400年包含的天数
//	前三个100年包含24个闰年76个平年;第四个100年是25个闰年75个平年
#define _400_years_day_ ((24 * 366 + 76 * 365) * 3 + 25 * 366 + 75 * 365)
//	一个4年包含的天数,3个平年,一个闰年:(3*365+366)
#define _4_years_day_ (3*365+366)

//	判断年份year是否是闰年.
bool is_leap_year(int year)
{
	bool bRes = false;
	//	若year不是4的倍数,则不是闰年
	if (year % 4 != 0)	return false;
	//	若year是4的倍数、但不是100的倍数,则是闰年
	if (year % 100 != 0) return true;
	//	若year是4的倍数、并且是100的倍数、还是400的倍数,则是闰年
	if (year % 400 == 0) return true;
	//	若year是4的倍数、并且是100的倍数、但不是400的倍数,则不是闰年
	return false;
}
//	计算year年有多少天
int get_year_days(int year)
{
	//	闰年366天
	if (is_leap_year(year)) return 366;
	//	平年365天
	return 365;
}

//	计算前n年的总天数.
int compute_n_yers_day(int n)
{
	if (0 == n) return 0;
	int nRes = 0;
	div_t divRes;	//	整数除法运算的结果
	divRes = div(n, 400);	//	包含几个400年
	nRes += divRes.quot * _400_years_day_;
	//	包含几个100年.
	divRes = div(divRes.rem, 100);
	nRes += divRes.quot * _100_years_day_;
	//	包含几个4年
	divRes = div(divRes.rem, 4);
	nRes += divRes.quot * _4_years_day_;
	//	余数是几个平年
	nRes += divRes.rem * 365;
	return nRes;
}
//	计算y年前m个月的天数(m取值范围是0到11)
int compute_month_days(int year, int m)
{
	int nRes = 0;
	int nFebDays = 0;	//	2月份的天数.
	if (is_leap_year(year)) nFebDays = 29;	//	闰年29天
	else nFebDays = 28;	//	平年28天
	
	switch (m) {
	case 0:
		nRes = 0;
		break;
	case 1:
		nRes = 31;
		break;
	case 2:
		nRes = 31+nFebDays;
		break;
	case 3:
		nRes = 31+nFebDays+31;
		break;
	case 4:
		nRes = 31+nFebDays+31+30;
		break;
	case 5:
		nRes = 31+nFebDays+31+30+31;
		break;
	case 6:
		nRes = 31 + nFebDays + 31 + 30 + 31+30;
		break;
	case 7:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30+31;
		break;
	case 8:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30 + 31+31;
		break;
	case 9:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30 + 31 + 31+30;
		break;
	case 10:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30 + 31 + 31 + 30+31;
		break;
	case 11:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31+30;
		break;
	case 12:
		nRes = 31 + nFebDays + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30+31;
		break;
	}
	return nRes;
}

//	计算y年m月d日是第几天.
//	基准是:公元1年1月1日是第一天.
//	算法是:前(y-1)年的天数+前(m-1)个月的天数+d
int ymd_to_day(int y, int m, int d)
{
	return compute_n_yers_day(y - 1) + compute_month_days(y, m-1) + d;
}

void day_to_ymd(int day, int& y, int& m, int& d)
{
	//	计算年份
	y = 1;
	div_t divRes;	//	整数除法运算的结果
	divRes = div(day, _400_years_day_);	//	包含几个400年
	y += divRes.quot * 400;
	//	包含几个100年.
	divRes = div(divRes.rem, _100_years_day_);
	y += divRes.quot * 100;
	//	包含几个4年
	divRes = div(divRes.rem, _4_years_day_);
	y += divRes.quot * 4;
	//	包含是几个平年
	divRes = div(divRes.rem, 365);
	y += divRes.quot * 1;
	
	//	现在,利用余数计算月份和天数.
	short int sDay = divRes.rem;
	//	如果余数为0,表示是该年的最后一天,需做特殊处理.
	if (0 == sDay) {
		y -= 1;
		sDay = get_year_days(y);
	}
	if (sDay <= compute_month_days(y, 1)) {	//	小于或等于1月份的天数
		m = 1; d = sDay;
	}else if (sDay <= compute_month_days(y, 2)) {	//	小于或等于2月份的天数
		m = 2; d = sDay- compute_month_days(y, 1);
	}else if (sDay <= compute_month_days(y, 3)) {	//	小于或等于3月份的天数
		m = 3; d = sDay - compute_month_days(y, 2);
	}else if (sDay <= compute_month_days(y, 4)) {	//	小于或等于4月份的天数
		m = 4; d = sDay - compute_month_days(y, 3);
	}else if (sDay <= compute_month_days(y, 5)) {	//	小于或等于5月份的天数
		m = 5; d = sDay - compute_month_days(y, 4);
	}else if (sDay <= compute_month_days(y, 6)) {	//	小于或等于6月份的天数
		m = 6; d = sDay - compute_month_days(y, 5);
	}else if (sDay <= compute_month_days(y, 7)) {	//	小于或等于7月份的天数
		m = 7; d = sDay - compute_month_days(y, 6);
	}else if (sDay <= compute_month_days(y, 8)) {	//	小于或等于8月份的天数
		m = 8; d = sDay - compute_month_days(y, 7);
	}else if (sDay <= compute_month_days(y, 9)) {	//	小于或等于9月份的天数
		m = 9; d = sDay - compute_month_days(y, 8);
	}else if (sDay <= compute_month_days(y, 10)) {	//	小于或等于10月份的天数
		m = 10; d = sDay - compute_month_days(y, 9);
	}else if (sDay <= compute_month_days(y, 11)) {	//	小于或等于11月份的天数
		m = 11; d = sDay - compute_month_days(y, 10);
	}else if (sDay <= compute_month_days(y, 12)) {	//	小于或等于12月份的天数
		m = 12; d = sDay - compute_month_days(y, 11);
	}
}

//	测试is_leap_year.
void test_is_leap_year(int year)
{
	//int year = 100;
	if (is_leap_year(year))
		std::cout << "公元" << year << "年是闰年" << std::endl;
	else
		std::cout <<"公元" << year << "年不是闰年" << std::endl;
}
//	测试年月日和天数的互转
void test_ymd_day(int y, int m, int d)
{
	//	年月日到天、天到年月日的测试
	int day = ymd_to_day(y, m, d);
	std::cout << "公元" << y << "年" << m << "月" << d << "日是第" << day << "天" << std::endl;
	day_to_ymd(day, y, m, d);	//	天数转换为年月日
	std::cout << "第" << day << "天是公元" << y << "年" << m << "月" << d << "日" << std::endl;
	std::cout << std::endl;
}

int main()
{
	//	闰年判断函数的测试.
	test_is_leap_year(1);	//	不是闰年
	test_is_leap_year(100);	//	不是闰年
	test_is_leap_year(200);	//	不是闰年
	test_is_leap_year(2022);//	不是闰年
	test_is_leap_year(4);	//	是闰年
	test_is_leap_year(20);	//	是闰年
	test_is_leap_year(400);	//	是闰年
	test_is_leap_year(2000);	//	是闰年
	test_is_leap_year(2020);	//	是闰年
	
	//	计算第一个400年是多少天.(每个400年的天数是相同的)
	int n_400_years_days = 0;
	for (int i = 1; i <= 400; i++)
		n_400_years_days += get_year_days(i);
	std::cout << "第一个400年的天数是(第一种方法):" << n_400_years_days << std::endl;
	//	也可以用如下算法计算,以检验正确性.	
	//	前三个100年包含24个闰年76个平年;第四个100年是25个闰年75个平年
	//	所以一个400年的天数是: (24*366+76*365)*3 + 25*366+75*365
	std::cout << "第一个400年的天数是(第二种方法):" << (24 * 366 + 76 * 365) * 3 + 25 * 366 + 75 * 365 << std::endl;

	//	年月日到天、天到年月日的测试
	int year = 1; int month = 1;  int day = 1;
	test_ymd_day(year, month, day);
	
	year = 1; month = 1, day = 31;
	test_ymd_day(year, month, day);

	year = 1; month = 3, day = 1;
	test_ymd_day(year, month, day);
	
	year = 1; month = 12, day = 31;
	test_ymd_day(year, month, day);

	year = 2; month = 1, day = 1;
	test_ymd_day(year, month, day);

	year = 3; month = 12, day = 31;
	test_ymd_day(year, month, day);

	year = 4; month = 12, day = 31;
	test_ymd_day(year, month, day);

	year = 2022; month = 2, day = 27;
	test_ymd_day(year, month, day);
}

上述代码中的核心函数是ymd_to_day和day_to_ymd,分别实现年月日到天数的转换和天数到年月日的转换;is_leap_year,判断某年是否是闰年;get_year_days,输入年份,返回该年的天数;compute_n_yers_day,计算前n年的总天数,即公元1年至n年的总天数;compute_month_days,计算某年前m个月的总天数(实现是简单的,但是不够简洁);test_is_leap_year和test_ymd_day是两个功能测试函数。
main函数主要是产生测试数据,测试上述相关函数的功能。
程序运行结果如下图所示:

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alexabc3000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值