年月周星期计算年月日 C++

年月周星期计算年月日 C++

题目

输入年、月、第几周、周几,输出对应的 年、月、日。

参考资料

1.https://blog.csdn.net/qq_42403069/article/details/86305578
2.https://blog.csdn.net/u011017652/article/details/17229781

注意

如果有错,欢迎指正!
一、每一周定义有两种:
1.周日到周六
2.周一到周日
这两种不同的定义可能会导致不同的计算结果。这里的代码放入的是第一种定义的结果,若想改为第二种,需要调整代码中的b[ ]和后续代码。下面所述全部以第一种定义为基础。
图1
图二
二、“第几周”的定义

  1. 每周的第一周和最后一周一般不完整,如上图(以周日-周六为一周为例):2018年2月的第一周从周四开始,第一周没有周日、周一、周二、周三;最后一周没有周四、周五、周六。
  2. 每个月份的周数有一定范围,不存在“第0周”、“第7周”、“第8周”的说法。

思路

主要是在搜索相关问题时,发现基姆拉尔森计算公式的存在,利用该公式求出每月1号的星期数。根据求得的星期可以判断输入是否正确,例如:输入2019 07 1 7(2019年7月第1周周日),是错误输入,因为该月第一周没有周日。
以输入2019 07 3 2为例,首先计算2019年7月1日是星期一,计算第一周天数,计算第二周天数,计算第三周天数,累加之后判断是否超过该月最大的天数,超过就返回0,未超过就计算出了号数。

c++代码

周日到周六为一周:


#include<iostream>
#include<iomanip>
using namespace std;
//基姆拉尔森计算公式计算某年某月某日对应的星期
int CaculateWeekDay(int yy, int mm, int d)
{
	if (mm == 1 || mm == 2) {
		mm += 12;
		yy--;
	}
	int iWeek = (d + 2 * mm + 3 * (mm + 1) / 5 + yy + yy / 4 - yy / 100 + yy / 400) % 7;
	return iWeek + 1;
}

int a[][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 b[8] = { 0,1,2,3,4,5,6,0 };
//判断是否是闰年
int IsLeapYear(int y)
{
	if ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
		return 1;
	else return 0;
}

int CaculateDay(int yy, int mm, int w, int n)
{
	//输入判断是否符合条件
	if (mm < 1 || mm>12) return 0;
	if (w < 1 || w>6) return 0;
	if (n < 1 || n>7) return 0;
	int week = CaculateWeekDay(yy, mm, 1);//计算每月1号星期
	int days;
	if (w == 1)
	{
		if (b[n] < b[week])
			return 0;
		else
			days = b[n] -b[week] + 1;
	}
	else
	{
		days = b[6] - b[week]+1;
		for (int i = 2; i <=w-1; i++)
		{
			days += 7;
		}
		if (n == 7) days += 1;
		else  days += n + 1;

		if (days <= 0 || days > a[IsLeapYear(yy)][mm - 1])
			return 0;
	}
	return days;
}


int main()
{
	int yy, mm, w, n;
	cin >> yy >> mm >> w >> n;
	int day = CaculateDay(yy, mm, w, n);
	if (day == 0)
		cout << day << endl;
	else
	{
		cout << yy << "-" << setw(2) << setfill('0') << mm << "-" << setw(2) << setfill('0')<< day << endl;
	}
    return 0;
}

输入:2018 12 1 7
输出:0

输入:2019 07 3 2
输出:2019-07-16

周一到周日为一周

#include<iostream>
#include<iomanip>
using namespace std;

int CaculateWeekDay(int yy, int mm, int d)
{
	if (mm == 1 || mm == 2) {
		mm += 12;
		yy--;
	}
	int iWeek = (d + 2 * mm + 3 * (mm + 1) / 5 + yy + yy / 4 - yy / 100 + yy / 400) % 7;
	return iWeek + 1;
}

int a[][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 b[8] = { 0,1,2,3,4,5,6,7 };

int IsLeapYear(int y)
{
	if ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
		return 1;
	else return 0;
}

int CaculateDay(int yy, int mm, int w, int n)
{
	//输入判断是否符合条件
	if (mm < 1 || mm>12) return 0;
	if (w < 1 || w>6) return 0;
	if (n < 1 || n>7) return 0;
	int week = CaculateWeekDay(yy, mm, 1);//计算每月1号星期
	int days;
	if (w == 1)
	{
		if (b[n] < b[week])
			return 0;
		else
			days = b[n] - b[week] + 1;
	}
	else
	{
		days = b[7] - b[week] + 1;
		for (int i = 2; i <= w - 1; i++)
		{
			days += 7;
		}
		days += b[n] - b[1] + 1;

		if (days <= 0 || days > a[IsLeapYear(yy)][mm - 1])
			return 0;
	}
	return days;
}

int main()
{
	int yy, mm, w, n;
	cin >> yy >> mm >> w >> n;
	int day = CaculateDay(yy, mm, w, n);
	if (day == 0)
		cout << day << endl;
	else
	{
		cout << yy << "-" << setw(2) << setfill('0') << mm << "-" << setw(2) << setfill('0')<< day << endl;
	}
	return 0;
}


输入:2018 12 1 7
输出:2018-12-02
输入:2019 07 3 2
输出:2019-07-16

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值