/* CalendarDate.java ** Java instance class that provides for the representation and manipulation ** of calendar dates. ** ** Authors: P.M.J. & R.W.M. & < STUDENT's NAME > ** Collaborators: ... ** Known Defects: ... */ import java.util.Calendar; import java.util.Date; import java.text.DecimalFormat; public class CalendarDate { // public constants (for the days of the week) // ------------------------------------------ public final int SUNDAY = 1; public final int MONDAY = 2; public final int TUESDAY = 3; public final int WEDNESDAY = 4; public final int THURSDAY = 5; public final int FRIDAY = 6; public final int SATURDAY = 7; // default values // -------------- private static final int DEFAULT_MONTH = 1; private static final int DEFAULT_DAY = 1; private static final int DEFAULT_YEAR = 2000; // instance variables // ------------------ private int month; // must be in range [1..12] private int day; // must be in range [1..monthDays(month,year)] private int year; // must be non-negative // constructors // ------------ /** Initializes this calendar date to the default. */ public CalendarDate() { month = DEFAULT_MONTH; day = DEFAULT_DAY; year = DEFAULT_YEAR; } /** Initializes this calendar date to that described by the given ** parameters. An IllegalArgumentException is thrown if the ** parameters do not describe an actual date. ** ** @param mm initial value for month ** @param dd initial value for day ** @param yyyy initial value for year */ public CalendarDate(int mm, int dd, int yyyy) throws IllegalArgumentException { setDate(mm,dd,yyyy); } /** Initializes this calendar date to be that described by the ** parameter, assumed to be in mm/dd/yyyy form. If the parameter ** is not of the correct form, or it fails to describe an actual ** date, an IllegalArgumentException is thrown. ** @param date expected to be in the form mm/dd/yyyy */ public CalendarDate(String date) throws IllegalArgumentException { setDate(date); } // observers // --------- /** Returns the current month value. ** @return the current month value */ public int getMonth() { return month; } /** Returns the current day value. ** @return the current day value */ public int getDay() { return day; } /** Returns the current year value. ** @return the current year value */ public int getYear() { return year; } /** Returns an integer value representing the day of the week, ** corresponding to the public constants, SUNDAY, MONDAY, etc. ** @return 1=SUNDAY, 2=MONDAY, ..., 7=SATURDAY */ public int getDayOfWeek() { Calendar c = Calendar.getInstance(); c.setTime(new Date((year-1900),(month-1),day)); int dow = c.get(Calendar.DAY_OF_WEEK); //1=sunday, 2=monday, etc. return dow; } // mutators // -------- /** Sets this calendar date to that described by the three parameters. ** An IllegalArgumentException is thrown if they do not describe an ** actual date. ** @param mm new value for month ** @param dd new value for day ** @param yyyy new value for year */ public void setDate(int mm, int dd, int yyyy) throws IllegalArgumentException { if (isValidDay(mm,dd,yyyy)) { month = mm; day = dd; year = yyyy; } else { throw new IllegalArgumentException("invalid calendar date value"); } } /** Sets this calendar date to that described by the parameter, which is ** expected to be in mm/dd/yyyy format. If the string is not properly ** formatted, or if it fails to describe an actual date, an ** IllegalArgumentException is thrown. ** @param date expected to be in mm/dd/yyyy form */ public void setDate(String date) throws IllegalArgumentException { int m = mmddyyyyMonthOf(date); int d = mmddyyyyDayOf(date); int y = mmddyyyyYearOf(date); setDate(m,d,y); } /* Sets this calendar date to be a duplicate of the given one. ** @param that CalendarDate object whom this calendar date is made to ** be a duplicate of. */ public void setDate(CalendarDate that) { this.setDate(that.month, that.day, that.year); } /** Sets the month value part of this calendar date to the given value. ** In the event that the given month value is invalid (e.g., 18) or ** the resultant date would be invalid (e.g., February 30), an ** IllegalArgumentException is thrown. ** @param mm new value for month */ public void setMonth(int mm) throws IllegalArgumentException { String errorMessage = "invalid month or potential calendar date value"; if (isValidDay(mm, this.day, this.year)) { this.month = mm; } else { throw new IllegalArgumentException(errorMessage); } } /** Sets the day value part of this calendar date to the given value. ** In the event that the given day value is invalid (e.g., 45) or ** the resultant date would be invalid (e.g., February 30), an ** IllegalArgumentException is thrown. ** @param dd new value for day */ public void setDay(int dd) throws IllegalArgumentException { String errorMessage = "invalid day or potential calendar date value"; if (isValidDay(this.month, dd, this.year)) { this.day = dd; } else { throw new IllegalArgumentException(errorMessage); } } /** Sets the year value part of this calendar date to the given value. ** In the event that the given year value is invalid (e.g., -23) or ** the resultant date would be invalid (e.g., February 29, 1945), an ** IllegalArgumentException is thrown. ** @param yyyy new value for year */ public void setYear(int yyyy) throws IllegalArgumentException { String errorMessage = "invalid year or potential calendar date value"; if (isValidDay(this.month, this.day, yyyy)) { this.year = yyyy; } else { throw new IllegalArgumentException(errorMessage); } } /** Moves this calendar date one day backward in time. */ public void retreatDay( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date one day forward in time. */ public void advanceDay( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of days backward in time. ** @param n the number of days by which to move backwards; ** must be non-negative. */ public void retreatDay(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of days forward in time. ** @param n the number of days by which to move forwards; ** must be non-negative. */ public void advanceDay(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date one week backward in time. */ public void retreatWeek() { //CODE NEEDED HERE!!! } /** Moves this calendar date the one week forward in time. */ public void advanceWeek( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of weeks backward in time. ** @param n the number of weeks by which to move backwards; ** must be non-negative. */ public void retreatWeek(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of weeks forward in time. ** @param n the number of weeks by which to move forwards; ** must be non-negative. */ public void advanceWeek(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date one month backward in time. */ public void retreatMonth( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date one month forward in time. */ public void advanceMonth( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of months backward in time. ** @param n the number of months by which to move backwards; ** must be non-negative. */ public void retreatMonth(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of months forward in time. ** @param n the number of months by which to move forwards; ** must be non-negative. */ public void advanceMonth(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date one year backward in time. */ public void retreatYear( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date one year forward in time. */ public void advanceYear( ) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of years backward in time. ** @param n the number of years by which to move backwards; ** must be non-negative. */ public void retreatYear(int n) { //CODE NEEDED HERE!!! } /** Moves this calendar date the specified number of years forward in time. ** @param n the number of years by which to move forwards; ** must be non-negative. */ public void advanceYear(int n) { //CODE NEEDED HERE!!! } // standard methods // ---------------- /** Returns a string representation, in mm/dd/yyyy format, of this ** calendar date. ** @return an expression of this date in mm/dd/yyyy format */ @Override public String toString( ) { String fmt = "%02d"; DecimalFormat nf = new DecimalFormat("##"); return String.format(fmt,month) + "/" + String.format(fmt,day) + "/" + year; } /** Reports whether this calendar date is equal to the given object; ** throws IllegalArgumentException if the given object is not an ** instance of this class. ** @param that, an Object to compare to this calendar date ** (expected to be a CalendarDate object) ** @return true iff 'that' is an instance of this class and represents ** the same calendar date as does 'this'; */ @Override public boolean equals(Object that) { if (that instanceof CalendarDate) { return this.equals((CalendarDate)that); } else { throw new IllegalArgumentException("not a CalendarDate object"); } } /** Reports whether this calendar date is equal to the given calendar date. ** @param that, a CalendarDate object to compare to this calendar date ** @return true iff 'that' represents the same calendar date as does 'this'; */ public boolean equals(CalendarDate that) { // REPLACEMENT CODE NEEDED HERE!! return false; } /** Compares this calendar date to the given object; throwing an ** IllegalArgumentException if the given object is not an instance ** of this class. ** @param that, an Object to compare to this object ** (expected to be a CalendarDate object) ** @return a positive integer if this calendar date comes later than ** the one represented by 'that'; a negative integer if this ** calendar date comes before the one represented by 'that'; ** zero if they coincide. */ public int compareTo(Object that) { if (that instanceof CalendarDate) { return this.compareTo((CalendarDate)that); } else { throw new IllegalArgumentException("not a CalendarDate object"); } } /** Compares this calendar date to the given one. ** @param that, a CalendarDate object to compare to this object ** @return a positive integer if this calendar date comes later than ** the one represented by 'that'; a negative integer if this ** calendar date comes before the one represented by 'that'; ** zero if they coincide. */ public int compareTo(CalendarDate that) { //REPLACEMENT CODE NEEDED HERE!!! return 0; } // private methods // --------------- /* Returns true iff the three parameters describe an actual date. */ private boolean isValidDay(int month, int day, int year) { return year >= 0 && isValidMonth(month) && day >= 1 && day <= monthDays(month,year); } /* Returns true iff the given month value is valid. */ private boolean isValidMonth(int month) { return month >= 1 && month <= 12; } /* Returns the number of days in the given year. */ private int yearDays(int year) { int result = 365; if(isLeapYear(year)) { result = 366; } return result; } /* Returns the number of days in the given month of the given year. */ private int monthDays(int month, int year) { int result; // Assert: (month >= 1) && (month <=12) if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) { result = 30; } else if(month == 2) { if (isLeapYear(year)) { result = 29; } else { result = 28; } } else { // month is one of 1, 3, 5, 7, 8, 10, or 12 result = 31; } return result; } /* Returns true iff the given year is a leap year. */ private boolean isLeapYear(int year) { return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0); } /* Returns the month component, as an int, of the given string, which ** is expected to describe a calendar date using the mmddyyyy format. */ private int mmddyyyyMonthOf(String dateStr) { int posOfSlash = dateStr.indexOf('/'); String monthStr = dateStr.substring(0,posOfSlash); return Integer.parseInt(monthStr); } /* Returns the day component, as an int, of the given string, which ** is expected to describe a calendar date using the mmddyyyy format. */ private int mmddyyyyDayOf(String dateStr) { int posOf1stSlash = dateStr.indexOf('/'); int posOfLastSlash = dateStr.lastIndexOf('/'); String dayStr = dateStr.substring(posOf1stSlash+1, posOfLastSlash); return Integer.parseInt(dayStr); } /* Returns the year component, as an int, of the given string, which ** is expected to describe a calendar date using the mmddyyyy format. */ private int mmddyyyyYearOf(String dateStr) { int posOfLastSlash = dateStr.lastIndexOf('/'); String yearStr = dateStr.substring(posOfLastSlash+1); return Integer.parseInt(yearStr); } }