程序功能:
1. 利用组合的原理(composition),在现有的Date类和Time类的基础上,创建新的类:DateAndTime类。
2. DateAndTime类的无参构造函数创建一个当前的系统时间戳。
运行结果示例:
日期:2019年1月1日,时间:5:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:6:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:7:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:8:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:9:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:10:03:13 PM 一小时后的时间为:日期:2019年1月1日,时间:11:03:13 PM 一小时后的时间为:日期:2019年1月2日,时间:12:03:13 AM 一小时后的时间为:日期:2019年1月2日,时间:1:03:13 AM 一小时后的时间为:日期:2019年1月2日,时间:2:03:13 AM …… 一小时后的时间为:日期:2019年1月22日,时间: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