目录
- 前言
- 问题描述
- 思路分析
- 解决方案
- 方案一
- 方案二
- 方案三
- 方案四
- 结语
前言
-
1、平年指阳历没有闰日或农历没有闰月的年份,闰年是公历中的名词,是为了弥补因人为历法规定造成的年度天数与地球实际公转周期的时间差而设立的,补上时间差的年份为闰年,闰年共有366天;
-
2、平年的二月份只有28天,而闰年的二月份有29天;
-
3、闰年的都能被4整除,而平年一般不可以,闰年分为普通闰年和世纪闰年,能被4整除但不能被100整除的年份为普通闰年,如果是世纪年,必须被400整除才是闰年,否则就是平年。
问题描述
二月是一个有趣的月份,平年的二月有28天,闰年的二月有29天。闰年每四年一次,在判断闰年时,可以使用年份除以4,如果能够整除,则该年是闰年。
本例要求编写一个程序,从键盘输入年份,根据输入的年份计算这一年的2月有多少天。在计算二月份天数时,可以使用日期时间类的相关方法实现。
思路分析
使用Java的Scanner类创建一个扫描器对象,用于接受键盘数据,然后利用Scanner的nextInt方法获取输入的值,跟你的实际需求进行逻辑处理就好了。
解决方案
根据上述的思路分析,我们直接上代码。
方案一
📌普通版
这是很多新手刚入门时最常写的,比较简略。
package com.gx.demo;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接受键盘数据
Scanner sc = new Scanner(System.in);
// 提示输入一个年份
System.out.println("请输入一个年份:");
int year = sc.nextInt();
// 定义一个平年的天数,默认28(平年)
int days = 28;
// 闰年:(1)和 (2)只要满足一个就行,则表示这一年是闰年, (1)能被4整除 但不能被100整除;(2)能被400整除。
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
days++;
// days++的含义:符合if逻辑就+1,即 = days + 1
}
// 输出当年二月的天数,整形和字符串拼接 输出的是字符串
System.out.println(year + "年份的二月份共有" + days + "天");
// 关闭输入 计算机回收资源
sc.close();// 凡是属于IO流的类如果不关闭,会一直占用资源,要养成好习惯,用完就关掉
}
}
执行结果:(列举部分可能会出现的输入操作) |
- 1.输入一个闰年年份:2020
请输入一个年份:
2020
2020年份的二月份共有29天
- 2.输入一个平年年份:2021
请输入一个年份:
2021
2021年份的二月份共有28天
- 3.输入负数:-2020
请输入一个年份:
-2022
-2022年份的二月份共有28天
- 4.输入非数字:dsaf好的
请输入一个年份:
dsaf好的
Exception in thread “main” java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at com.gx.demo.Test5.main(Test5.java:12)
抛输入不匹配异常
- 5.输入带空格:20 20
请输入一个年份:
20 20
20年份的二月份共有29天
总结:
-
1.上面的程序并没有很好的提示输入的年份是闰年还是平年,我们只能依靠二月份的28天或29天去区分,所以接下来我们会在方案二中进行增加一个标识来区分闰年还是平年作为返回区分。
-
2.除了1,2正常输入并且是我们想要的效果,其他的输入都是不太友好的,因此我们需要将这些可能会出现的结果考虑进去,对程序做一个兼容。那么我们怎么针对3,4,5来做一个容错呢?请看下面方案二:
方案二
📌进阶版
针对方案一的个别问题,我们对方法进行一次优化,增加部分逻辑判断。
package com.gx.demo;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接受键盘数据
Scanner sc = new Scanner(System.in);
// 提示输入一个年份
System.out.println("请输入一个年份:");
int year = 0;
// 判断键盘输入是否是int类型,且大于0
if (sc.hasNextInt()) {
// 请输入一个整形数字,表示年份
year = sc.nextInt();
// 判断不能为负数
if (year < 0) {
System.out.println("输入的年份类型错误,需为正整数:");
return;// 直接结束,不往下执行
}
} else {
System.out.println("输入的年份类型错误:");
return;// 直接结束,不往下执行
}
// 定义一个平年的天数,默认28(平年)
int days = 28;
// 定义平/闰年标识,默认是false(平年)
boolean isleapyear = false;
// 闰年:(1)和 (2)只要满足一个就行,则表示这一年是闰年, (1)能被4整除 但不能被100整除;(2)能被400整除。
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
isleapyear = true;
days++;
// days++的含义:符合if逻辑就+1,即 = days + 1
}
// 判断是平年/闰年
if (isleapyear) {
// 输出当年二月的天数,整形和字符串拼接 输出的是字符串
System.out.println(year + "年是闰年," + "该年的二月份共有" + days + "天");
} else {
System.out.println(year + "年是平年," + "该年的二月份共有" + days + "天");
}
// 关闭输入 计算机回收资源
sc.close();// 凡是属于IO流的类如果不关闭,会一直占用资源,要养成好习惯,用完就关掉
}
}
执行结果:(列举部分可能会出现的输入操作) |
- 1.输入一个闰年年份:2020
请输入一个年份:
2020
2020年是闰年,该年的二月份共有29天
- 2.输入一个平年年份:2021
请输入一个年份:
2021
2021年是平年,该年的二月份共有28天
- 3.输入负数:-2022
请输入一个年份:
-2022
输入的年份类型错误,需为正整数:
- 4.输入非数字:dsaf好的
请输入一个年份:
dsaf好的
输入的年份类型错误:
- 5.输入带空格:20 20
请输入一个年份:
20 20
20年是闰年,该年的二月份共有29天
总结:
-
1.方案二中增加了 isleapyear 变量标识,实现了简单区分年份对应的是闰年还是平年的判断;
-
2.通过执行结果可以看出,方案二对方案一中的3,4点都进行了兼容判断,使用hasNextInt判断输入的是否为整数,但是由于int的范围包含负数,所以还得判断年份大于0;
-
3.由于使用了nextInt,导致不能直接调用字符串中针对空格去除的方法,所以这一步优化将在方案三中使用nextLine来替换nextInt;
-
4.nextInt方法根据分隔符(回车,空格等)只取出输入的流中分割的第一部分并解析成Int。
方案三
📌终极版
对输入的年份存在空格的情况进行替换空格的操作。
package com.gx.demo;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接受键盘数据
Scanner sc = new Scanner(System.in);
// 提示输入一个年份
System.out.println("请输入一个年份:");
String num = "";
Integer year = 0;
// 判断键盘输入是否是int类型,且大于0
if (sc.hasNextInt()) {
// 请输入一个整形数字,表示年份
num = sc.nextLine();
year = Integer.valueOf(num.replace(" ", ""));
// 判断不能为负数
if (year < 0) {
System.out.println("输入的年份类型错误,需为正整数:");
return;// 直接结束,不往下执行
}
} else {
System.out.println("输入的年份类型错误:");
return;// 直接结束,不往下执行
}
// 定义一个平年的天数,默认28(平年)
int days = 28;
// 定义平/闰年标识,默认是false(平年)
boolean isleapyear = false;
// 闰年:(1)和 (2)只要满足一个就行,则表示这一年是闰年, (1)能被4整除 但不能被100整除;(2)能被400整除。
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
isleapyear = true;
days++;
// days++的含义:符合if逻辑就+1,即 = days + 1
}
// 判断是平年/闰年
if (isleapyear) {
// 输出当年二月的天数,整形和字符串拼接 输出的是字符串
System.out.println(year + "年是闰年," + "该年的二月份共有" + days + "天");
} else {
System.out.println(year + "年是平年," + "该年的二月份共有" + days + "天");
}
// 关闭输入 计算机回收资源
sc.close();// 凡是属于IO流的类如果不关闭,会一直占用资源,要养成好习惯,用完就关掉
}
}
执行结果:(列举部分可能会出现的输入操作) |
- 1.输入一个闰年年份:2020
请输入一个年份:
2020
2020年是闰年,该年的二月份共有29天
- 2.输入一个平年年份:2021
请输入一个年份:
2021
2021年是平年,该年的二月份共有28天
- 3.输入负数:-2022
请输入一个年份:
-2022
输入的年份类型错误,需为正整数:
- 4.输入非数字:dsaf好的
请输入一个年份:
dsaf好的
输入的年份类型错误:
- 5.输入带空格:20 20
请输入一个年份:
20 20
2020年是闰年,该年的二月份共有29天
总结:
-
1.使用了nextLine之后,由于返回值是String类型,所以先进行类型转换,然后再调用字符串的替换
replace
方法去空格; -
2.nextLine()方法返回的是输入回车之前的所有字符,可以获得空格符,所以这里直接调用
replace
替换空格符就好; -
3.要区分Scanner中next方法、nextLine方法(常用)和nextInt方法是实际含义。
方案四
📌标准版
由于上面的问题描述中,需求标明在计算二月份天数时,可以使用日期时间类的相关方法实现,因此这里将增加一个计算天数的方法来调用。
package com.gx.demo;
import java.util.Calendar;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接受键盘数据
Scanner sc = new Scanner(System.in);
// 提示输入一个年份
System.out.println("请输入一个年份:");
String num = "";
Integer year = 0;
// 判断键盘输入是否是int类型,且大于0
if (sc.hasNextInt()) {
// 请输入一个整形数字,表示年份
num = sc.nextLine();
year = Integer.valueOf(num.replace(" ", ""));
// 判断不能为负数
if (year < 0) {
System.out.println("输入的年份类型错误,需为正整数:");
return;// 直接结束,不往下执行
}
} else {
System.out.println("输入的年份类型错误:");
return;// 直接结束,不往下执行
}
// 调用calDay方法计算天数
int days = calDay(year);
// 定义平/闰年标识,默认是false(平年)
boolean isleapyear = false;
// 闰年:(1)和 (2)只要满足一个就行,则表示这一年是闰年, (1)能被4整除 但不能被100整除;(2)能被400整除。
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
isleapyear = true;
days = calDay(year);// 调用calDay方法计算天数,重新赋值给days
}
// 判断是平年/闰年
if (isleapyear) {
// 输出当年二月的天数,整形和字符串拼接 输出的是字符串
System.out.println(year + "年是闰年," + "该年的二月份共有" + days + "天");
} else {
System.out.println(year + "年是平年," + "该年的二月份共有" + days + "天");
}
// 关闭输入 计算机回收资源
sc.close();// 凡是属于IO流的类如果不关闭,会一直占用资源,要养成好习惯,用完就关掉
}
/**
* 利用Calendar计算某年的二月份天数
*
* @param year 年份
* @return
*/
public static int calDay(int year) {
Calendar c = Calendar.getInstance();
c.set(year, 2, 1);// year年的3月1日
c.add(Calendar.DAY_OF_MONTH, -1);// 将3月1日往左偏移一天结果是2月的天数
return c.get(Calendar.DAY_OF_MONTH);
}
}
执行结果:参考方案三 |
到此就完成了,代码都是很简单的判断,没啥技术难点,很适合新手入门,赶紧去试试吧!祝“码”到成功!
结语
此方案仅供参考,你可以根据自行的需求进行优化,具体需要实现什么逻辑,继续添加就好。Scanner里面的方法还是很多的,有兴趣的朋友可以花时间去研究每个方法的含义。