学以致用——Java源码——增强的自定义日期类(包含nextDay方法)(Enhancing Class Date with nextDay method)

功能介绍:

1. 使用年、月、日构建日期

2. 对年、月、日进行了合法性检查,创建成功的日期都是合法的日期。合法性检查包括:每个月的天数、闰年(存在2月29日)、平年(不存在2月29日)

3. 返回任意日期的nextDay(带参数方法),无参方法可用于循环输出下一日

注:看似简单的一次增强,也花掉了不少时间!

运行结果示例:

d1:20181231

d2:201811

d4:2018228

d5:191811

d7:201911

20181231日的下一天是:201911

 

201911日的下一天是:201812

 

2019228日的下一天是:201931

 

2019330日的下一天是:2019331

 

2019331日的下一天是:201941

 

2019430日的下一天是:201951

 

201961日的下一天是:201962

 

 

 

当前日期是:20181231日,之后500天分别为:

 

Day 1201911

Day 2201912

Day 3201913

……

Day 4982020512

Day 4992020513

Day 5002020514

 

代码:

1. 实体类(Date)

import java.util.Calendar;


//JHTP Exercise 8.8: Enhancing Class Date
//by pandenghuang@163.com
/**
 * 8.8 (Enhancing Class Date) Modify class Date of Fig. 8.7 to perform error
 * checking on the initializer values for instance variables month, day and year
 * (currently it validates only the month and day). Provide a method nextDay to
 * increment the day by one. Write a program that tests method nextDay in a loop
 * that prints the date during each iteration to illustrate that the method
 * works correctly. Test the following cases: a) incrementing into the next
 * month and b) incrementing into the next year.
 */

public class Date {
	private static int month; // 1-12
	private static int day; // 1-31 based on month
	private static int year; // any year

	private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

//constructor: confirm proper value for month and day given the year
	public Date(int year, int month, int day) {
		// check for year up to next year and later than 1918 //2018年12月添加
		if (year < 1918 || year > Calendar.getInstance().get(Calendar.YEAR) + 100) // 获取下一年的下100年
			throw new IllegalArgumentException(
					"year (" + day + ") out-of-range. A year later than 1918 and up to next 100 years is expected.");

		// check if month in range
		if (month <= 0 || month > 12)
			throw new IllegalArgumentException("month (" + month + ") must be 1-12");

		// check if day in range for month
		if (day <= 0 || (day > daysPerMonth[month] && !(month == 2 && day == 29)))
			throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");

		// check for leap year if month is 2 and day is 29
		// 闰年判定规则:能被400整除,或,能被4整除但不能被100整除
		if (month == 2 && day == 29 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
			throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");

		Date.month = month;
		Date.day = day;
		Date.year = year;

		
		  //System.out.printf( "日期对象创建成功:%s%n", this);
		 
	}

	public Date() {
		Date.year = Calendar.getInstance().get(Calendar.YEAR);
		Date.month = Calendar.getInstance().get(Calendar.MONTH) + 1;
		Date.day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
	}

//return a String of the form month/day/year
	public String toString() {
		return String.format("%d年%d月%d日", year, month, day);
	}

//增加一天,2018年12月添加
	public static Date nextDay(int year, int month, int day) {
//数据校验逻辑(与构造函数相同)
		// check for year up to next year and later than 1918 //2018年12月添加
				if (year < 1918 || year > Calendar.getInstance().get(Calendar.YEAR) + 100) // 获取下一年的下100年
					throw new IllegalArgumentException(
							"year (" + day + ") out-of-range. A year later than 1918 and up to next 100 years is expected.");

				// check if month in range
				if (month <= 0 || month > 12)
					throw new IllegalArgumentException("month (" + month + ") must be 1-12");

				// check if day in range for month
				if (day <= 0 || (day > daysPerMonth[month] && !(month == 2 && day == 29)))
					throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");

				// check for leap year if month is 2 and day is 29
				// 闰年判定规则:能被400整除,或,能被4整除但不能被100整除
				if (month == 2 && day == 29 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
					throw new IllegalArgumentException("day (" + day + ") out-of-range for the specified month and year");


		switch (month) {
//1月,3月,5月,7月,8月,10月和12月为小月,每月31天	
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			if (day + 1 > 31) {
				day = 1;
				if (month + 1 > 12) {// 如果是12月31日,加一天后进入新的一年的第一天(元旦)
					month = 1;
					++year;
				} else
					++month;
			} else
				++day; // 非月末,日期直接加一
			break;
//4月,6月,9月和11月为小月,每月30天	
		case 4:
		case 6:
		case 9:
		case 11:
			if (day + 1 > 30) {
				day = 1;
				month = month + 1; // 进入下一月1号
			} else
				++day; // 非月末,日期直接加一
			break;
		case 2:// 2月既不是大月,也不是小月
			if (month == 2 && day == 29 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 闰年,2月为29天
				day = 1;
				month = month + 1; // 月份前进为3月份
			} else if (month == 2 && day == 28 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 平年,2月为28天
				day = 1;
				month = month + 1; // 月份前进为3月份
			} else
				++day; // 非月末,日期直接加一
			break;

		}
		return new Date(year, month, day);
	}

//返回当前日期的下一天,2018年12月添加
	public static Date nextDay() {

		int year = Date.year;
		int month = Date.month;
		int day = Date.day;

		switch (month) {
//1月,3月,5月,7月,8月,10月和12月为小月,每月31天	
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			if (day + 1 > 31) {
				day = 1;
				if (month + 1 > 12) {// 如果是12月31日,加一天后进入新的一年的第一天(元旦)
					month = 1;
					++year;
				} else
					++month;
			} else
				++day; // 非月末,日期直接加一
			break;
//4月,6月,9月和11月为小月,每月30天	
		case 4:
		case 6:
		case 9:
		case 11:
			if (day + 1 > 30) {
				day = 1;
				month = month + 1; // 进入下一月1号
			} else
				++day; // 非月末,日期直接加一
			break;
		case 2:// 2月既不是大月,也不是小月
			if (month == 2 && day == 29 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 闰年,2月为29天
				day = 1;
				month = month + 1; // 月份前进为3月份
			} else if (month == 2 && day == 28 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) { // 平年,2月为28天
				day = 1;
				month = month + 1; // 月份前进为3月份
			} else
				++day; // 非月末,日期直接加一
			break;

		}

		return new Date(year, month, day);
	}

	
} // end class Date

2. 测试类

public class DateTest {
	public static void main(String[] args) {

        //测试带参数构造器
		System.out.printf("d1:%s%n", new Date(2018, 12, 31));
		System.out.printf("d2:%s%n", new Date(2018, 1, 1));
		//System.out.printf("d3:%s%n",new Date(2119, 2, 28));
		System.out.printf("d4:%s%n", new Date(2018, 2, 28));
		System.out.printf("d5:%s%n", new Date(1918, 1, 1));
		// System.out.printf("d6:%s%n",new Date(1917,12,31));
		System.out.printf("d7:%s%n", new Date(2019, 1, 1));

		//测试带参数nextDay方法
		System.out.printf("2018年12月31日的下一天是:%s%n%n", Date.nextDay(2018, 12, 31));
		System.out.printf("2019年1月1日的下一天是:%s%n%n", Date.nextDay(2018, 1, 1));
		System.out.printf("2019年2月28日的下一天是:%s%n%n", Date.nextDay(2019, 2, 28));
		System.out.printf("2019年3月30日的下一天是:%s%n%n", Date.nextDay(2019, 3, 30));
		System.out.printf("2019年3月31日的下一天是:%s%n%n", Date.nextDay(2019, 3, 31));
		System.out.printf("2019年4月30日的下一天是:%s%n%n", Date.nextDay(2019, 4, 30));
		System.out.printf("2019年6月1日的下一天是:%s%n%n", Date.nextDay(2019, 6, 1));


		// 测试无参nextDay方法
		Date currentDay = new Date();// 日期初始化为当前日期
		System.out.printf("%n%n当前日期是:%s,之后500天分别为:%n%n", currentDay);
		for (int i = 1; i <= 500; i++) {
			System.out.printf("Day %d:%s%n", i,Date.nextDay()); // 打印下一天
		}

	}
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值