学以致用——Java源码——使用组合原理创建自定义日期时间类(DateAndTime)(Date and Time Class)

程序功能:

1. 利用组合的原理(composition),在现有的Date类和Time类的基础上,创建新的类:DateAndTime类。

2. DateAndTime类的无参构造函数创建一个当前的系统时间戳。

 

运行结果示例:

日期:201911日,时间:5:03:13 PM

一小时后的时间为:日期:201911日,时间:6:03:13 PM

一小时后的时间为:日期:201911日,时间:7:03:13 PM

一小时后的时间为:日期:201911日,时间:8:03:13 PM

一小时后的时间为:日期:201911日,时间:9:03:13 PM

一小时后的时间为:日期:201911日,时间:10:03:13 PM

一小时后的时间为:日期:201911日,时间:11:03:13 PM

一小时后的时间为:日期:201912日,时间:12:03:13 AM

一小时后的时间为:日期:201912日,时间:1:03:13 AM

一小时后的时间为:日期:201912日,时间:2:03:13 AM

……

一小时后的时间为:日期:2019122日,时间:1:03:13 PM

代码:

1. 自定义DateAndTime类

//JHTP Exercise 8.12: Date and Time Class
//by pandenghuang@163.com
/**
 * 
 * 8.12 (Date and Time Class) Create class DateAndTime that combines the 
 * modified Time2 class of Exercise 8.7 and the modified Date class of Exercise 8.8. 
 * Modify method incrementHour to call method nextDay if the time is incremented 
 * into the next day. Modify methods toString and toUniversalString to output the date 
 * in addition to the time. Write a program to test the new class DateAndTime.
 * Specifically, test incrementing the time to the next day.
 *
 */
public class DateAndTime {

	private static Date date = new Date();
	private static Time time = new Time();
	
	public static void displayDateAndTime () {
		System.out.printf("日期:%s,时间:%s%n",date,time);
	}
	
	public static void main(String[] args) {
		
		displayDateAndTime();
		
		for (int i=0;i<500;i++) {  //打印500小时以后的日期及使时间
		time.incrementHour();
		System.out.print("一小时后的时间为:");
		displayDateAndTime();
		}
		
	}
}

2. 自定义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

3. 自定义Time类

import java.util.Calendar;
//JHTP Exercise 8.5,8.7: Modifying the Internal Data Representation of a Class,Enhancing Class Time2
//by pandenghuang@163.com
/**(Modifying the Internal Data Representation of a Class) It would be
* perfectly reasonable for the Time2 class of Fig. 8.5 to represent 
* the time internally as the number of seconds since midnight rather 
* than the three integer values hour, minute and second. Clients could
* use the same public methods and get the same results. Modify the Time2
* class of Fig. 8.5 to implement the time as the number of seconds 
* since midnight and show that no change is visible to the clients 
* of the class.
* (Enhancing Class Time2) Modify class Time2 of Fig. 8.5 to include a tick method that increments
the time stored in a Time2 object by one second. Provide method incrementMinute to increment
the minute by one and method incrementHour to increment the hour by one. Write a
program that tests the tick method, the incrementMinute method and the incrementHour method
to ensure that they work correctly. Be sure to test the following cases:
a) incrementing into the next minute,
b) incrementing into the next hour and
c) incrementing into the next day (i.e., 11:59:59 PM to 12:00:00 AM).
*/
	// Fig. 8.5: Time2.java
	// Time2 class declaration with overloaded constructors.  

	class Time
	{
	   private int hour; // 0 - 23
	   private int minute; // 0 - 59
	   private int second; // 0 - 59

	   // Time no-argument constructor: 
	   // initializes each instance variable to system time
	   public Time()
	   {
		  hour =  Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		  minute =  Calendar.getInstance().get(Calendar.MINUTE);
		  second =  Calendar.getInstance().get(Calendar.SECOND);

	   } 
	   
	 //自定义时间类
	   public Time(int secondsPassed){
		   if (secondsPassed<=0){
			   throw new IllegalArgumentException("经过秒数不能为负!");
		   }
		   
		   this.second=secondsPassed%60;
		   this.minute=secondsPassed/60%60;
		   this.hour=(secondsPassed/60/60%60>=24)?0:secondsPassed/60/60%60;
	   }
	   
	   public Time(int hour, int minute, int second) 
	   { 
	      if (hour < 0 || hour >= 24)
	         throw new IllegalArgumentException("hour must be 0-23");

	      if (minute < 0 || minute >= 60)
	         throw new IllegalArgumentException("minute must be 0-59");

	      if (second < 0 || second >= 60)
	         throw new IllegalArgumentException("second must be 0-59");

	      this.hour = hour;
	      this.minute = minute; 
	      this.second = second; 
	   } 

	   // Time2 constructor: another Time2 object supplied
	   public Time(Time time)
	   {
	      // invoke constructor with three arguments
	      this(time.getHour(), time.getMinute(), time.getSecond());
	   } 

	   // Set Methods
	   // set a new time value using universal time; 
	   // validate the data
	   public void setTime(int hour, int minute, int second)
	   {
	      if (hour < 0 || hour >= 24)
	         throw new IllegalArgumentException("hour must be 0-23");

	      if (minute < 0 || minute >= 60)
	         throw new IllegalArgumentException("minute must be 0-59");

	      if (second < 0 || second >= 60)
	         throw new IllegalArgumentException("second must be 0-59");

	      this.hour = hour;
	      this.minute = minute; 
	      this.second = second; 
	   } 

	   // validate and set hour 
	   public void setHour(int hour) 
	   { 
	      if (hour < 0 || hour >= 24)
	         throw new IllegalArgumentException("hour must be 0-23");

	      this.hour = hour;
	   } 

	   // validate and set minute 
	   public void setMinute(int minute) 
	   { 
	      if (minute < 0 || minute >= 60)
	         throw new IllegalArgumentException("minute must be 0-59");

	      this.minute = minute; 
	   } 

	   // validate and set second 
	   public void setSecond(int second) 
	   { 
	      if (second < 0 || second >= 60)
	         throw new IllegalArgumentException("second must be 0-59");

	       this.second = second; 
	   } 

	   // Get Methods
	   // get hour value
	   public int getHour() 
	   { 
	      return hour; 
	   } 

	   // get minute value
	   public int getMinute() 
	   { 
	      return minute; 
	   } 

	   // get second value
	   public int getSecond() 
	   { 
	      return second; 
	   } 

	   // convert to String in universal-time format (HH:MM:SS)
	   public String toUniversalString()
	   {
	      return String.format(
	         "%02d:%02d:%02d", getHour(), getMinute(), getSecond());
	   } 

	   // convert to String in standard-time format (H:MM:SS AM or PM)
	   public String toString()
	   {
	      return String.format("%d:%02d:%02d %s", 
	         ((getHour() == 0 || getHour() == 12) ? 12 : getHour() % 12),
	         getMinute(), getSecond(), (getHour() < 12 ? "AM" : "PM"));
	   } 
	   
	 //增加一秒
	   public void tick(){
		   if(second+1<60)		   
			   second++;
		   else if (second+1==60){
			   second=0;
			   this.incrementMinute();
		   }
	   }
	   
	 //增加一分钟
	   public void incrementMinute(){
		   if(minute+1<60)		   
			   minute++;
		   else if (minute+1==60){
			   minute=0;
			   this.incrementHour();
		   }
	   }
	   
		 //增加一小时
	   public void incrementHour(){
		   if(hour+1<24)		   
			   hour++;
		   else if (hour+1==24){
			   hour = 0;
			   Date.nextDay();
		   }
	   }
	   
	} // end class Time

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值