一、代码运行截图
1.1 开始欢迎页面
-
提示输入年份和月份

1.2 展示日历页面
-
展示对应年月的日历,并继续提醒是否继续查找

1.3 继续输入页面

1.4 退出页面

二、实现思路
-
考虑不同情况
-
是否为闰年
-
每月的天数
-
周日-周六如何对应具体日期
-
-
当前年月日距离1900年1月1日间隔天数
-
同年同月不同日间隔(3月5日~3月20日):20-15=5天
-
间隔天数 = 终止日期 - 起始天数
-
需要:1月1日~1月15日
-
间隔天数 = 终止日期
-
同年不同月不同日间隔(1月15日~10月3日):(31-15) + 28/29 +31+30+31+30+31+31+30 + 3 = 242天 / 243天
-
间隔天数 = (起始月总天数 - 起始日期) + 对应月份的天数 * (起始月份-1 ~ 终止月份-1)月 + 终止日期
-
需要:1月1日~10月3日
-
间隔天数 = 1~9月整月天数 + 终止日期
-
不同年不同月不同日间隔(1900年1月1日~2025年10月3日):
-
计算思路:1900年1月1日 —> 2025年1月1日 —> 2025年10月3日
-
计算间隔年份 = 终止年 - 1900
-
计算整年天数间隔天数:可以不同完整算出来,使用while遍历即可,算出整年天数
-
计算不同月不同日间隔天数:1~终止月整月天数 + 终止日期
-
间隔天数 = 间隔年份 *对应年份天数 + 1~终止月整月天数 + 终止日期
-
三、总结
0、界面撰写
-
开始页面
-
继续查找月份页面
-
结束页面
-
注意输入异常的判断
1、输出的日历格式(important!!!)
-
标头的构造
-
先找到当月第一天为周几
-
再打印一开始的,空白部分
-
从1号开始遍历整个月,按照一定规律输出
-
遇到周六时,换行
2、计算间隔天数
-
计算间隔整年,并注意是否是不是闰年
-
计算整月月数
-
计算最后一个月的天数:注意:如果是1号,那也算一天,因此是
目标日期 - 1天
3、闰年计算
-
能被4整除,但不能被100整除的是闰年
-
能被400整除的是闰年
4、封装一个输入年月的类
-
创建一个新类YearMonth,变量为year和month,并创建全参构造函数
-
在万年历的类中,创建一个新的方法,用于接收输入的年和月,这样可以把在【开始页面】和【继续查找】页面上,直接新建一个YearMonth,去调用方法,即可同时返回年和月的数据
5、退出逻辑优化
-
将Calendar中的循环判断去除,放到welcome的页面中
-
创建一个boolean类型的标识符flag,默认为true(第一次默认出现是否查看),进行查看,并在输出当月的日历后,让用户做出判断,y继续,flag仍然为true,否则flag为false,跳出循环,程序结束
四、源代码
package com.yeban.base.Test;
import java.util.Scanner;
/**
* @Desc TODO
* @Author yeban
* @Date 2025/10/2
*/
// 万年历
public class PerpetualCalendar {
public void welcome() {
Scanner sc = new Scanner(System.in);
System.out.println("*-----------------欢迎使用万年历-----------------*");
boolean flag = true;
while(flag) {
// 判断是否继续查看万年历
System.out.println("请输入年份(1900以后):");
int year = sc.nextInt();
System.out.println("请输入月份:");
int month = sc.nextInt();
Calendar(year,month);
flag = next();
}
}
// 是否继续页面
public boolean next() {
Scanner sc = new Scanner(System.in);
System.out.println("------------继续---Y|y 退出----N|n------------");
String select = sc.next();
switch (select) {
case "Y":
case "y":
return true;
case "N":
case "n":
System.out.println("---------------感谢使用万年历!!!!---------------");
return false;
default:
System.out.println("输入选项错误!请重新输入!");
return next();
}
}
// important!!
// 显示月份,日期,星期:1900年1月1日 是 星期一
public void Calendar(int year, int month) {
System.out.print("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
System.out.println();
int days = daysOfMonth(year,month); //当月天数
int firstDayOffset = apartDays(year,month,1); // 当月第一天距离1900年1月1日的天数
int firstIndex = (firstDayOffset + 1) % 7; // 计算是星期几
// 打印空格
for(int i = 0; i < firstIndex; i++) {
System.out.print("\t\t");
}
// 打印日期
for(int i = 1; i <= days; i++) {
System.out.print(i + "\t\t");
if((i + firstIndex) % 7 == 0) { // 星期六就换行
System.out.println();
}
}
System.out.println();
}
// 目标日期与1900年1月1日相隔天数半段
public int apartDays(int year, int month, int day) {
// 相隔多少天,差几月,差几年
int days = 0;
int months = month - 1;
// 加整年间隔天数
for (int y = 1900; y < year; y++) {
days += isLeapYear(y) ? 366 : 365;
}
// 加差整月的天数
while(months != 0) {
days += daysOfMonth(year,months);
months --;
}
// 加最后一个月的天数,并返回
return days + day - 1;
}
// 判断闰年
public boolean isLeapYear(int year) {
// 闰年能被4整除,但不能被100整除
// 或者能被400整除的年份是闰年
if ( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ) {
return true;
}
return false;
}
// 判断月份对应的天数
public int daysOfMonth(int year, int month) {
int days = 0;
switch (month) {
// 一个月31天的月份
case 1: // January (一月)
case 3: // March (三月)
case 5: // May (五月)
case 7: // July (七月)
case 8: // August (八月)
case 10: // October (十月)
case 12: // December (十二月)
days = 31;
break;
// 一个月30天的月份
case 4: // April (四月)
case 6: // June (六月)
case 9: // September (九月)
case 11: // November (十一月)
days = 30;
break;
// 特殊的二月
case 2: // February (二月)
if(isLeapYear(year)) {
days = 29;
break;
} else {
days = 28;
break;
}
// 用户输入错误
default:
System.out.println("输入的月份有误!请重新输入!");
}
return days;
}
public static void main(String[] args) {
PerpetualCalendar c = new PerpetualCalendar();
// 进入欢迎界面
c.welcome();
}
}
7399

被折叠的 条评论
为什么被折叠?



