使用java实现简单的日期计算,可以通过自定义日期类来实现,具体实现如下:
一、Date自定义类
在自定义Date类中,创建year、month、days的私有属性代表日期的年、月、日。并创建Getter、Setter方法以及构造方法,在eclipse中可以通过alt+shift+s快捷键打开源码,并选择生成Getter和Setter,方法截图附在最后。在Date类中通过calculate()方法将传入的日期和当前对象的日期进行比对。通过proper()方法将验证日期的正确性,月份为1-12月,日期为1-N(N为当前月份的最大天数)代码如下:
public class Date {
private int year;//年份
private int month;//月份
private int days;//日期
// 有参构造函数
public Date(int year, int month, int days) {
super();
this.year = year;
this.month = month;
this.days = days;
}
// 无参构造函数
public Date() {
super();
}
// Setter和Getter方法
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 getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public int calculate(int newYear,int newMonth,int newDays) {
int ans = 0;//相差日期
int months[] = {0,31,28,31,30,31,30,31,31,30,31,30};//月份所含日期
int oldAllDays = 0;//第一个年份从一月一日开始统计的日期
int newAllDays = 0;//第二个年份从一月一日开始统计的日期
// 第一个年份到第二个年份中间所有的日期
// 闰年为366天,平年为365天
while(this.year < newYear) {
if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0) {
ans += 366;
}else {
ans += 365;
}
this.year++;
}
// 统计第一个年份所经过的日期
for (int i = 0; i < this.month; i++) {
// 当前年若为闰年则将二月改为29天
if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0) {
months[2] = 29;
}else {
months[2] = 28;
}
oldAllDays += months[i];
}
oldAllDays += this.days;
// 统计第二个年份所经过的日期
for (int i = 0; i < newMonth; i++) {
// 当前年若为闰年则将二月改为29天
if((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0) {
months[2] = 29;
}else {
months[2] = 28;
}
newAllDays += months[i];
}
newAllDays += newDays;
return ans - oldAllDays + newAllDays;
}
// 检查日期的正确性
public boolean proper() {
int months[] = {31,28,31,30,31,30,31,31,30,31,30,31};//每个月份所含日期
// 当年份为闰年时,二月即下标为1的位置改为29天
if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0) {
months[1] = 29;
}
if(this.month > 12 || this.month < 1) {//当输入月份小于1或者大于12时返回false
return false;
}else if(this.days > months[this.month - 1] || this.days < 1 ) {//当输入日期小于1或者大于当前月最大日期时返回false
return false;
}
return true;
}
}
如果要对年份做出正确判断,还可以在月份判断前加上年份的范围判断,min和max代表需要规范年份范围的下限和上限,代码如下:
if(this.year < min || this.year > max) {
return false;
}
二、Test类
在Test测试类中建立主函数main()进行测试,从键盘获取两个String类型的日期,并将其分割为年、月、日,调用Date类的proper()函数判断输入正误,再调用Date类的calculate()方法获得计算结果,并打印。具体代码如下:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean flag1 = true;//控制第一个日期的循环输入
boolean flag2 = true;//控制第二个日期的循环输入
Date date1 = new Date();//创建一个Date类的对象
while(flag1) {
// 从键盘接收第一个日期
System.out.println("请输入一个过去的日期(xxxx-xx-xx):");
String oldTime = input.next();
// 通过正则表达式检验输入日期格式时候正确
if(!oldTime.matches("[0-9]{4}-[0-9]{2}-[0-9]{2}")) {
System.out.println("输入格式错误!");
continue;
}
// 将获得的日期通过“-”进行截取
String[] oldTimes = oldTime.split("-");
// 将截取的年份、月份、日期取出并强制转化为int类型
int oldYear = Integer.parseInt(oldTimes[0]);
int oldMonth = Integer.parseInt(oldTimes[1]);
int oldDays = Integer.parseInt(oldTimes[2]);
// 通过Setter注入为对象属性添加值
date1.setYear(oldYear);
date1.setMonth(oldMonth);
date1.setDays(oldDays);
// 检查属性值得合法性
if(!date1.proper()) {
System.out.println("输入错误!");
continue;
}
flag1 = false;
}
Date date2 = new Date();//创建第二个对象
while(flag2) {
// 从键盘接收第二个日期
System.out.println("请输入当前日期(xxxx-xx-xx):");
String newTime = input.next();
if(!newTime.matches("[0-9]{4}-[0-9]{2}-[0-9]{2}")) {
System.out.println("输入格式错误!");
continue;
}
String[] newTimes = newTime.split("-");
int newYear = Integer.parseInt(newTimes[0]);
int newMonth = Integer.parseInt(newTimes[1]);
int newDays = Integer.parseInt(newTimes[2]);
date2.setYear(newYear);
date2.setMonth(newMonth);
date2.setDays(newDays);
if(!date2.proper()) {
System.out.println("输入错误!");
continue;
}
flag2 = false;
}
// 调用Date类的calculate方法计算输入日期与当前对象的相差日期
int days = date1.calculate(date2.getYear(), date2.getMonth(), date2.getDays());
// 打印输入结果
System.out.println("两个日期相隔" + days + "天");
}
}
上述代码中,对输入的日期通过正则表达式进行了格式规范,为xxxx-xx-xx。在通过split("-")方法对输入的日期通过“-”进行分割,储存在一个字符串数组中,然后使用int的封装类中的parseInt()方法分别对字符串数组中的字符串进行强制转换,最后获得Date类需要的年、月、日。两个while循环控制两个输入日期,输入正确则跳出循环,否则重新输入。通过创建boolean类型的变量控制循环体,错误则通过continue直接进入下一轮循环,否则执行到最后改变boolean的值跳出循环体。
三、运行结果
输入错误时运行结果如下图所示
输入正确格式及日期运行结果如下图所示
四、总结
1.Setter、Getter方法及构造方法
在自定义类中,如果想调用private(私有)的成员变量,可以通过Getter、Setter的方法。
快键键Alt+shift+s,并选择生成Setter和Getter,可以一键生成Getter和Setter方法。
除此以外,还可以选择使用字段生成构造函数生成构造函数
选择构造函数需要的参数,点击生成,如果都不选择,则为无参构造函数。
2.正则表达式
在java中如果要对输入字符串进行格式或者内容的验证,可以通过正则表达进行验证。在上述代码中,本人只使用了oldTime.matches("[0-9]{4}-[0-9]{2}-[0-9]{2}")对输入的日期进行格式验证,仅是为了方便字符串分割,如有需要还能直接通过正则表达式验证日期输入的正确性。