CMPS 144L Fall 2019
Lab #2: IncDate, SafeDate, and Exception Handling

Links to Java classes needed in this lab:


Activity #1: Finish IncDate

In Chapter 1 of the Dale/Joyce/Weems textbook, the Java class Date is presented. Instances of this class are immutable (i.e., their states cannot be changed) because the class includes no transformer/mutator methods by which to do so.

The authors then introduce IncDate as a child class (or subclass, if you prefer) of Date. The name is shorthand for "incrementable date", reflecting the fact that IncDate includes a transformer/mutator method, increment(), the purpose of which is to change the state of a date by moving it one day "forward" in time.

However, the authors do not provide a body for the increment() method. Your job is to do that. It is recommended that this method make use of the method isLastDayOfMonth(), which, like increment(), is given in stubbed form (meaning its body is essentially empty, waiting for you to supply correct code).

To make the task of developing the body of isLastDayOfMonth() easier, a class constant called DAYS_IN_MONTH has been included. It is an array whose k-th element contains the number of days in the k-th month of the year, for each relevant value of k (i.e., 1 through 12). (The 2nd element contains 28, corresponding to the number of days in February during a non-leap year.) Due to the existence of leap day, the required logic of isLastDayOfMonth() is a little tricky. To ease it a little, an isLeapYear() method is provided.1

There is no need for you to pay much attention to the Date class, except to notice that its three instance variables (year, month, and day) will need to be referred to in IncDate's increment() method. (This is possible because those variables were declared using the protected access modifier (rather than private).)

You can test your work using jGrasp's Workbench feature or the IncDateTester application. Of course, the input values that you provide when running this application should be chosen to maximize the likelihood that any logic errors in your code will be exposed.

When you are finished, submit your completed IncDate.java file to the Lab #2 folder.


Activity #2: Improve SafeDate

The textbook authors present a SafeDate class in Chapter 1 for the purpose of illustrating the throwing and handling of exceptions. Specifically, the class's constructor could detect, in some cases, whether the parameters passed to it described an invalid calendar date. When it did detect this, it threw a DateOutOfBoundsException (which was then handled in the client application program shown by the authors).

Your course instructor has modified the SafeDate class to make it a child of IncDate and so that its constructor does a better job of detecting cases when the parameters it receives do not describe a valid calendar date. In particular, after verifying that the month and year values make sense, it checks to see whether the day value makes sense with respect to the month and year.2 As in the authors' original version, if the date described is not valid, the constructor throws a DateOutOfBoundsException with an appropriate associated message.

What is left for you to do is

  1. supply a short code segment (where the comment MISSING CODE appears) that checks to see if the day value is valid and, if not, throws a DateOutOfBoundsException,
  2. provide the body of the isValidDay() method. Some helpful hints are included in the comments preceding the method.

When you are finished, submit your completed SafeDate.java file to the Lab #2 folder.


Activity #3: Improve SafeDateTester

As it stands, the SafeDateTester application prompts the user to enter integer values for month, day, and year in order to describe a calendar date. It then passes those values to the constructor of the SafeDate class in order to create an instance of that class representing that calendar date. If the described calendar date is valid, it is printed in M/D/Y format and the program terminates. Otherwise, it repeats the process just described. Thus, the program will not terminate until such time as the user has entered inputs describing a valid calendar date.

Oh, except that the program will terminate if the user causes it to crash by entering an input string that cannot be interpreted as an integer value. Specifically, the nextInt() method of the Scanner class will react to non-integer input by throwing an InputMismatchException (from the java.util package), which will make the program abort.

Your task is to modify the SafeDateTester program so that, rather than aborting in that situation, it prints a message telling the user that (s)he entered non-integer input and repeats the behavior of asking the user for input, etc.

To do this, you will need to insert a new catch block immediately after the one that catches DateOutOfBoundsException. You will need to make a few other adjustments to the code, too.

When you are finished, submit your completed SafeDateTester.java file to the Lab #2 folder.


Activity #4: Complete 2nd Constructor in Date Class

In the Date class you will notice that there is a second constructor (that is not in the textbook authors' version). The intent is for it to accept (via its formal parameter) a single number and to initialize the newly created object so that it represents the calendar date having that number as its Lilian Day Number. What has been given to you does not do that, however. You are to attempt to correct that.

The problem you face here is to translate a Lilian Day Number into values representing month, day, and year. Once you have those values, you can assign them to the corresponding instance variables.

What is suggested is that you make repeated calls to the lilian() method (the one having three parameters) as a way of searching for the correct (month,day,year) combination. For example, suppose that you were to make a first "guess" by calling lilian(9, 5, 2019) and that the resulting value was less than the Lilian Day Number that you were searching for. Then your next guess should be a date that comes after September 5, 2019. You can make an intelligent guess by taking account of the difference between the value returned by lilian() and the number that you're looking for. Repeat this process to "home in" on the right date.

When you are finished, submit your completed Date.java file to the Lab #2 folder.


Footnote

[1] But don't spend a lot of time fussing over the intricacies of leap day. Move on if you don't get it exactly right within a few minutes.

[2] Whether or not a month value is valid is independent of the year or day, and similarly the validity of a year value does not depend upon the month or day. But to determine the validity of a day value, one must take account of the month and, in the case of February, the year.