Java语言中自定义Date类
文章目录
一、实验目的:
1、掌握动态数组、静态数组的声明方式;
2、掌握重写Object类的toString()方法;
3、掌握重写Object类的equals()方法,实现对象的比较;
4、了解数组内存中的存储。
二、实验内容:
创建一个Date类:
(1)放在自创包中;
package experiment14.java;
(2)成员变量:
int year;
int month;
int day;
private int year;
private int month;
private int day;
(3)构造函数:
参数:int year,int month,int day
调用日期合法性检查方法,检查给定日期的合法性;如果是合法日期,则给成员变量赋初值;否则,提示给定日期非法。
public Date(int year, int month, int day) { // 包含三个参数的构造函数
this.year = year;
this.month = month;
this.day = day;
dateLegal(getYear(),getMonth(),getDay());
}
(4)成员方法:
a)检查日期合法性:
1、检查月份合法性:给定的月份month必须是1—12之间的数,否则非法;
2、检查日期合法性:1、3、5、7、8、10、12月份为“大月”,有31天;4、6、9、11为“小月”,只有30天;如果year被4整除且不能被100整除、或者year被400整除,为闰年;闰年2月份为29天,其余年份2月份为28天。
此方法是整个程序最重要的地方
根据以下代码:
因为要检查年月日三种值是否为合法的,所有从小到大进行条件判断:
先判断年份是否大于零,正确的话,运用setYear()方法对year变量进行赋值,如果小于等于零,那么运用setFlag(false),将flag值设置成false;
在正确的年份的条件内嵌套三个条件语句:判断是否是小月、大月、二月,或者不是1-12内的数的话,运用setFlag(false),将flag值设置成false;
其中,在小月和大月的条件语句中,运用setMonth()方法对month变量进行赋值,并且嵌套条件语句,判断天数是否是大月和小月的天数,如果天数正确的话,运用setDay()方法对day变量进行赋值。如果天数不正确的话运用setFlag(false),将flag值设置成false;
最后,在判断month是否为二月时,运用setMonth()方法对month变量进行赋值,再判断年份是否为闰年,然后天数是否时对应2月的天数,如果是的话运用setDay()方法对day变量进行赋值,如果天数不正确的话运用setFlag(false),将flag值设置成false;
到此,我们才算完成对年月日三个变量的合法性判断。建议读者看完后,自己实践一下,可以更好理解这段文字。
public void dateLegal(int year, int month, int day) { // 检查日期合法性方法
if (year>0){ // 年份合法
setYear(year);
if (month==4 || month==6 || month==9 || month==11){ // 小月
setMonth(month);
if (day>=1 && day<=30){ // 小月天数合法
setDay(day);
}else{ // 小月天数不合法
setFlag(false);
// System.out.println("天数出错30");
}
}
else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { // 大月
setMonth(month);
if (day>=1 && day<=31) { // 大月天数合法
setDay(day);
}else{ // 大月天数不合法
setFlag(false);
// System.out.println("天数出错31");
}
}
else if (month == 2) { // 2月
setMonth(month);
if (leapYear(year)){ // 闰年
if (day>=1 && day<=29){ // 闰年2月天数合法
setDay(day);
}else{ // 闰年2月天数不合法
setFlag(false);
// System.out.println("天数出错29");
}
}else{ // 非闰年
if (day>=1 && day<=28){ // 非闰年2月天数合法
setDay(day);
}else{ // 非闰年2月天数不合法
setFlag(false);
// System.out.println("天数出错28");
}
}
}
else{ // 月份不合法
setFlag(false);
// System.out.println("月份出错");
}
}
else{ // 年份不合法
setFlag(false);
// System.out.println("年份出错");
}
}
b)静态方法:给定年份、月份,返回该月的最后一天:
根据给定的年份、月份,返回该月份的最后1天的日期。如给定2000年2月,返回29;2019年7月,返回31等等;
在写本方法时,可以用enum枚举类型进行编写,也可以使用if-else if-else多分支语句进行编写;
这里使用switch case语句进行编写返回大月和小月的天数,
并用,if-else语句进行判断年份是否为闰年,并根据判断结果输出2月的天数。
public static int lastDay(int year, int month){ // 给定年份和月份,返回该月最后一天
switch (month){ // 匹配大月,返回31天
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
}
switch (month){ // 匹配小月,返回30天
case 4:
case 6:
case 9:
case 11:
return 30;
}
if (leapYear(year) && month == 2){ // 判断是否为年份为闰年并且月份为2月
return 29; // 返回闰年和非闰年情况下2月的最后一天的天数
}else{
return 28;
}
}
c) 静态方法:给定年份,判断是否为闰年;
根据:如果year被4整除且不能被100整除、或者year被400整除,为闰年;闰年2月份为29天,其余年份2月份为28天。
或根据之前的分支条件实验,进行简化代码,得到以下方法。
public static boolean leapYear(int year){ // 给定年份判断是否为闰年
return (year % 4 == 0 & year % 100 != 0) || year % 400 == 0;
}
d)重写Object的toString()方法:
使得其输出格式符合中国的习惯,按“xxxx年xx月xx日”格式输出。
重写toString方法,根据flag值判断要输出什么
@Override
public String toString() { // 重写toString方法名
if(isFlag()) {
return year + "年" + month + "月" + day + "日";
}else{
return "日期出错";
}
}
e)重写Object的equals()方法:
可以进行不同对象,进行年、月2个成员比较。首先,比较年份和月份,如两者一致返回true,否则返回false。
由题目可知,只需比较年份和月份两个变量是否相等。
@Override
public boolean equals(Object date) { // 重写equals方法
Date date1=(Date)date;
if (this == date){ // 判断地址是否相等
return true;
}
if (date == null || getClass() != date.getClass()) { // 判断值是否为空或者类是否相等
return false;
}
return year==date1.year && month==date1.month;
}
完整代码
package experiment14.java;
class Main{
public static void main(String[] args) {
Date date = new Date(2023,8,20);
Date date1 = new Date(2023,8,20);
Date date2 = new Date(2022,8,20);
Date date3 = new Date(2023,4,20);
Date date4 = new Date(2023,8,30);
Date date5 = new Date(2001,2,28);
Date date6 = new Date(2001,2,29);
System.out.println(date5.getYear() + "是闰年" + " " + Date.leapYear(date5.getYear()));
System.out.println(date.getYear() + "年" + date.getMonth() + "月" + " " + "有" + Date.lastDay(date.getYear(), date.getMonth()) + "天"); // 输出该年该月有多少天
System.out.println(date + " " + date1 + " " + date.equals(date1)); // 全相等,结果相等
System.out.println(date + " " + date2 + " " + date.equals(date2)); // 年份不相等,结果不相等
System.out.println(date + " " + date3 + " " + date.equals(date3)); // 月份不相等,结果不相等
System.out.println(date + " " + date4 + " " + date.equals(date4)); // 日数不相等,结果相等
System.out.println(date5); // 调用toString方法。可输出
System.out.println(date6); // 调用toString方法,不可输出
}
}
public class Date {
private int year;
private int month;
private int day;
private boolean flag = true;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public Date(){ // 空参构造函数
}
public Date(int year, int month, int day) { // 包含三个参数的构造函数
this.year = year;
this.month = month;
this.day = day;
dateLegal(getYear(),getMonth(),getDay());
}
public static boolean leapYear(int year){ // 给定年份判断是否为闰年
return (year % 4 == 0 & year % 100 != 0) || year % 400 == 0;
}
public static int lastDay(int year, int month){ // 给定年份和月份,返回该月最后一天
switch (month){ // 匹配大月,返回31天
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
}
switch (month){ // 匹配小月,返回30天
case 4:
case 6:
case 9:
case 11:
return 30;
}
if (leapYear(year) && month == 2){ // 判断是否为年份为闰年并且月份为2月
return 29; // 返回闰年和非闰年情况下2月的最后一天的天数
}else{
return 28;
}
}
public void dateLegal(int year, int month, int day) { // 检查日期合法性方法
if (year>0){ // 年份合法
setYear(year);
if (month==4 || month==6 || month==9 || month==11){ // 小月
setMonth(month);
if (day>=1 && day<=30){ // 小月天数合法
setDay(day);
}else{ // 小月天数不合法
setFlag(false);
// System.out.println("天数出错30");
}
}
else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { // 大月
setMonth(month);
if (day>=1 && day<=31) { // 大月天数合法
setDay(day);
}else{ // 大月天数不合法
setFlag(false);
// System.out.println("天数出错31");
}
}
else if (month == 2) { // 2月
setMonth(month);
if (leapYear(year)){ // 闰年
if (day>=1 && day<=29){ // 闰年2月天数合法
setDay(day);
}else{ // 闰年2月天数不合法
setFlag(false);
// System.out.println("天数出错29");
}
}else{ // 非闰年
if (day>=1 && day<=28){ // 非闰年2月天数合法
setDay(day);
}else{ // 非闰年2月天数不合法
setFlag(false);
// System.out.println("天数出错28");
}
}
}
else{ // 月份不合法
setFlag(false);
// System.out.println("月份出错");
}
}
else{ // 年份不合法
setFlag(false);
// System.out.println("年份出错");
}
}
@Override
public String toString() { // 重写toString方法名
if(isFlag()) {
return year + "年" + month + "月" + day + "日";
}else{
return "日期出错";
}
}
@Override
public boolean equals(Object date) { // 重写equals方法
Date date1=(Date)date;
if (this == date){ // 判断地址是否相等
return true;
}
if (date == null || getClass() != date.getClass()) { // 判断值是否为空或者类是否相等
return false;
}
return year==date1.year && month==date1.month;
}
}
运行结果
实验小结
在输出错误的信息时,我们还可以设置三个flag分别是对年份、月份、天数的正误,然后在重写toString()方法中,可以针对哪个值是false,输出哪种错误。
我们可以把大月和小月分别放在一个数组中,在判断某个数是否包含在某个数组中时,比如,大月放在bigMonths[]中,可以用,Arrays.asList(bigMonths).contains(month);