//: MyDate.java /** Simple date class * @author Mark Crocker <mcrocker@micron.net> * @author http://www.markcrocker.com/~mcrocker/ * @version 0.96 */ package com.markcrocker.thoughtworks; import java.io.*; import java.util.*; public class MyDate { private static int[] monthLength = {31,28,31,30,31,30,31,31,30,31,30,31}; // Number of days in each month. private static int[] monthOffset = {0,31,59,90,120,151,181,212,243,273,304,334}; // Number of days in year prior to current month private int leapMonth; // The number of days to add to the date to // accomodate the leap day in this year. Depends // on whether month is after February or not. private int leapOffset; // The number of days to add for all the // leap days in the previous years. private int debugLevel = 0; // Vestigal 1960s style debugging tool. private int date; // Date as the number of days since 1900-Jan-01 /** MyDate primary constructor. Converts date to an internal format for * storage and checks for invalid or out of range dates. * @param year year past 1900 (0-199). Ex: 1981 will be year 81, 2009 is 109. * @param month month of the year (1-12). * @param day day of the month (1-28,29,30, or 31) depending on the month. * @exception BadDateException thrown if the date is malformed or out of range. */ MyDate(int year, int month, int day) throws BadDateException { if (debugLevel > 2) { System.out.println("MyData instance constructed with year = " + year + " month = " + month + " day = " + day); } /* First check for valid year and month. These are fixed, so its an easy check */ if ((year < 0) || (year > 199) || (month < 1) || (month > 12)) { throw new BadDateException("-->Error in Year (= " + year + ") or Month (= " + month + ")"); } /* Before checking for valid day, need to figure out leap days. * Also take advantage of the logic to do the leap day offset * calculation.*/ leapMonth = 0; // Default. if (year%4 == 0) { // Is it a leap year? if (year > 4) { // Dont need previous years leap days until 1905 leapOffset = (year-1)/4; // Leap days for all previous years. } else { leapOffset = 0; } if (month == 2) { // Is it February? leapMonth = 1; } else if (month > 2) { // Is it after February? leapOffset += 1; // Can count leap day of this year. } // Must be January, nothing else required. } else { // NOT a leap year. leapOffset = year/4; // Leap days for all previous years, this one doesnt have one. } /* Check for valid day using leapMonth info */ if ((day < 1) || (day > monthLength[month-1] + leapMonth)) { throw new BadDateException("-->Error in Day (= " + day + " where Month = " + month + ")"); } /* Finally, decode date into internal format (ie: an integer * representing the number of days since 1900-Jan-01). */ date = day + monthOffset[month-1] + leapOffset + year*365; // Actual date calculation. } /** getDate. Mostly used in calculating date arimthmatic. * @return Returns date as the number of days since 1900-Jan-01. */ public int getDate() { return date; } /** setDebugLevel. Sets debugLevel variable for 1960s style debugging. * @deprecated Only used during code development. */ public void setDebugLevel(int dLevel) { debugLevel = dLevel; } /** toString. Java default string converter. * @return Returns date as a string that represents the number of days since 1900-Jan-01. */ public String toString() { return Integer.toString(date); } /** between. Calculates the number of days between two dates. Commutative and exclusive. * @return Returns number of days between two dates (exclusive). */ public int between(MyDate someOtherDate) { int between = Math.abs(date - someOtherDate.getDate())-1; // basic calculation. if (between < 0) // have to watch for case where the two dates are the same. between = 0; return between; } } ///:~ /* Todo ------- 1. Change date range from 0-199 to 1900-2099. */