题目:输入年份和月份,程序自动输出该月份的月历。例如,输入2019年10
月,则输出下图:
![a09d01ce8c1930a2a28abc6e0d771dbf.png](https://i-blog.csdnimg.cn/blog_migrate/37ee6d028b872b717532445984a1dce0.png)
已知条件为:1900年1月1日是星期一。
分析:
根据” 1900年1月1日是星期一”这个条件,我们可在草稿纸上画出1900年1月的月历,如下图
![5e394accb977a0bf7701b13d4efd84b0.png](https://i-blog.csdnimg.cn/blog_migrate/e43a519d0bc801ada786b0169c15d857.png)
我们假定“1900年的1月1日是第1天”从图中可以发现输出形式是7天一循环,具体如下:
1900年的1月1日是周一,第1天,(1%7=1)
1月2日是周二,第2天 ,(2%7=2)
…,
1月6日是周六,第6天,(6%7=6)
1月7日是周日,第7天 ,(7%7=0) (用0代表周日)
1月8日是周一 ,第8天,(8%7=1)
1月9日是周二, 第9天,(9%7=2)
…,
1月28日是周日,第28天,(28%7=0)
…,
再画出1900年2月的月历,如下图:
![dfb5084bda192b91cd16314b93d2bc00.png](https://i-blog.csdnimg.cn/blog_migrate/1347176fe51cc4f174ac9ecb24c26759.png)
2月2日是周五,第33天,(33%7=5)
2月3日是周六,第34天,(34%7=6)
通过例举,我们发现:若某天是从1900年的1月1日起的第n天,则那天就是周x(x等于n%7的值)。比如:1900年2月3日是第34天,则那天就是周6 (6=34%7)。
我们要打印某个月的月历,就需要知道当月第一天是周几,然后依次输出当月的日子(1--30,或1--31,或1--28,或1--29等),并在每个周六当天输出回车符换行即可,如图:
![b64c1a2f7c555b8a4a47ae9facc0c258.png](https://i-blog.csdnimg.cn/blog_migrate/bd1c079b205ad0691ed93619c8c40ec5.png)
但有一个问题:假如已经知道1990年2月的第一天是周四,但从图可知,周四前还有一些空格。那么在1990.02.01前有几个空格呢?
![ceb81a61a55da55fb01ebcdec78d636f.png](https://i-blog.csdnimg.cn/blog_migrate/0e7909a81358f6bb68bb832cdf3d8c41.png)
数一下,4个!也就是说,如果某个月的第一天是周4,那么前面就有4个空格,而周4可以写成 n%7 (n就是指1900.02.01是第n天),因此1990.02.01前有n%7个空格。
综上,本题大体思路已经明了了:先通过循环计算出2019年10月1日是第几天(从1900年1月1日开始计数),然后根据月历格式,7天一回车即可。
本题完整源码如下
public static void main(String[] args) {
// 首先计算2019.10.01是第几天
// 1900.1.1(第1天) - 2019-10.1(第n天)
// 第一步:(1)1900-2018 整个年份包含的天数
// 第二步:(2) 2019.1 - 2019.9 整个月份包含的天数
Scanner input = new Scanner(System.in);
System.out.println("请输入年份:");
int year = input.nextInt();
System.out.println("请输入月份:");
int month = input.nextInt();
int days = 0;
//1900-2018 整个年份包含的天数
for (int i = 1900; i < year; i++) {//1900 - 2018
//如果一个年份能够4整除 且不能被100整除 ; 或 一个数字能被400整除
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) days += 366;
else days += 365;
}
//2018.12.31
//2019.1.1 ->2019.9.30
for (int i = 1; i < month; i++) {//每一月
switch (i) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days += 31;
break;
case 4:
case 6:
case 9:
case 11:
days += 30;
break;
default:
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
days += 29;
} else {
days += 28;
}
}
}//2019.9.30
days++;//2019.10.1
// 星期n = 天数% 7 ;
int xingQi = days % 7;
System.out.println("星期日t星期一t星期二t星期三t星期四t星期五t星期六");
//根据观察可得: 星期几 前面有几个空格(占位符)
//空格(占位) ,占位符的个数 就是 星期n
for (int i = 0; i < xingQi; i++) {
System.out.print("tt");//Idea输出两个/t,Eclipse输出一个/t
}
//定义当月有多少天
int daysOfMonth = -1;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
daysOfMonth = 31;
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
daysOfMonth = 30;
} else {//2
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {//run
daysOfMonth = 29;
} else {
daysOfMonth = 28;
}
}
//数字1-31(日期)
for (int i = 1; i <= daysOfMonth; i++) {
System.out.print(i + "tt");
if ((xingQi + i) % 7 == 0) {
System.out.println();//回车
}
}
}
运行结果如图所示。
![94ef08fcdb6724ba2d5a0aa37a4722f1.png](https://i-blog.csdnimg.cn/blog_migrate/ae6c4b3fbc2d10e65411397d6291595c.jpeg)
还没看明白?没关系,看本题视频教程吧(从视频第27:50分钟开始)
Java基础_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
- 完 -
推荐阅读
Java小白到大神的心路历程(Java SE)
Java小白到大神的心路历程(Web前端)
答疑 | 面试全对,却没offer?
"hello"+null = ?
读者交流 | JAVA过时了吗?
自己写的java.lang.String能用吗?
答疑 | synchronized有指令重排序的功能吗?
服了,list.add()也会报错!!!
一道JVM面试题,答错率超90%
10行代码2道题,全答对的你月薪多少了?
自己写的java.lang.String能用吗?
基础 | 一道题彻底搞懂二重循环