V22.0101 ..... Homework 4 ..... Fall 2006
Calendar Dates
Assigned: Wed Oct 11
Due: Tue Oct 17 at midnight.
Write a program which implements a class Date, as follows.
The data fields (instance variables), which are all integers, are:
The methods are:
- a constructor that constructs an object of class date, using
3 integer parameters to define the year, month and day.
- a second constructor with no parameters that calls the first to construct
an object
with a random year between 1500 and 2500, a random month between 1 and 12,
and a random day between 1 and 31. Note that this might construct an
invalid date (as could the first one). Use Math.random(), which
returns a double
between 0 and 1; you can use this to generate a random integer in the required
range (think about this carefully, to make sure you cover all possibilities,
and make sure each day between 1 and 31 is equally likely, each month between
1 and 12 is equally likely, and each year between 1500 and 2500 is equally
likely.)
- a method display (no explicit parameter, no return value)
that displays the date of the object defined
by the implicit parameter, writing out the name of the month and using blanks
wisely.
- a method leapYear (no explicit parameter, returns boolean)
that determines whether or
not the year instance parameter of the object defined by the
implicit parameter is a leap year (see below for further discussion).
- a method monthLength (no explicit parameter, returns int)
that determines the length (in days)
of the month given by the month instance parameter of the object
defined by the implicit parameter.
Notice that monthLength needs to call
leapYear if month happens to be 2 (February).
- a method valid (no explicit parameter, returns boolean)
that returns true if the date given by the implicit parameter is valid,
checking the day, month and year values. The first valid date is the
year the Gregorian calendar was adopted: October 15, 1582. This method
needs to call monthLength (but not leapYear).
- a method equals (one explicit Date parameter, returns boolean)
that returns true if the dates given by the IMPLICIT Date parameter and
the EXPLICIT Date parameter are the same.
We will see next week why it is better to use type Object than type Date,
but use Date for now.
- a method later (one explicit Date parameter, returns boolean)
that returns true if the date given by the IMPLICIT Date parameter is
LATER than the date given by the EXPLICIT Date parameter.
- a method advanceDay that advances the date of the object
defined by the implicit parameter by ONE day. Don't forget that this
could involve the month and year as well as the day value.
- a method dayOfWeek (no explicit parameter, returns int)
that figures out the day of the week of the date given by the implicit
parameter. Return 0 for Sunday, 1 for Monday, etc. This method needs to
- construct a baseDate object for which we know the day of the week.
Any date will do, but it will make things easier to choose a Sunday.
- figure out whether the date given by the implicit parameter is equal to,
later than, or earlier than the base date. Note: you don't need to write
an earlier method - why not?
- if the two dates are not equal, use a while or
do...while loop to repeatedly call advanceDay with an
explicit parameter tempDate object which is constructed with
an appropriate initial date, keeping track of how many times advanceDay
is called, until you know how many days there are between the two dates.
You can then use the "mod" operator % to figure out the day of the week.
Make sure this method does not have a side effect! That is, make sure
that calling it does not change the implicit parameter object! This may
very well happen if you are not careful, so check by making a test that
displays the date both before and after calling dayOfWeek.
The main method should not be part of class Date.
It should be part of class TestDate, your outer class that tests the
Date class. In particular, it should test the dayOfWeek method.
It should demo a few example dates, by constructing objects such as your
birthday and famous dates from history, as well as a few random dates
(using the random constructor). It should then prompt the user
to enter his/her own test dates, reading them using JOptionPane or
Scanner. The valid method should be called to make sure a date is
valid before calling the dayOfWeek method.
You should print out the day of the week in a nice format, writing out
the name, not just printing the integer returned by dayOfWeek. (You could
use another method to translate the integer to the name of the day.)
A few more comments:
- Output should occur only in the main method and the display method.
- Leap years are those years divisible by 4, except those years,
such as 1800, 1900 and 2100, that are divisible by 100 but not
by 400.
- Make sure your program works for any valid date, including
any date in the future that does not cause integer overflow.
Start by testing your program on dates close to baseDate, such as the day
before or the day after, and then work up to dates further away, such as
your birthday or famous dates from history.
- We will be using the Date class as a basis for a more complicated
assignment involving engagement calendars later in the semester.
- If you don't find this challenging enough already, you can add some
extensions to handle years that preceded the adoption of the
Gregorian calendar. The Gregorian reform in 1582 introduced the
leap year rule given above. Before that, leap years occurred once every
four years without exception, going back to the time of Julius Caesar
(this was the Julian calendar). There is an 11 day gap between the
two calendars, making up for the leap years that would not have been
leap years under the Gregorian rule. However, this extension is not
required.
- You can easily check your dayOfWeek computations by looking at
calendars on the web, or doing "cal month year" on a Unix system.
However, be suspicious of dates before 1753, as the Gregorian reform
was not adopted in England until 1752, and, for example, the Unix
cal program treats dates as they were used in England.