Source of Day.java


  1: public class Day
  2: {
  3:    /**
  4:       Constructs a day with a given year, month, and day
  5:       of the Julian/Gregorian calendar. The Julian calendar
  6:       is used for all days before October 15, 1582
  7:       @param aYear a year != 0
  8:       @param aMonth a month between 1 and 12
  9:       @param aDate a date between 1 and 31
 10:    */
 11:    public Day(int aYear, int aMonth, int aDate)
 12:    {
 13:       year = aYear;
 14:       month = aMonth;
 15:       date = aDate;
 16:    }

 18:    /**
 19:       Returns the year of this day
 20:       @return the year
 21:    */
 22:    public int getYear()
 23:    {
 24:       return year;
 25:    }

 27:    /**
 28:       Returns the month of this day
 29:       @return the month
 30:    */
 31:    public int getMonth()
 32:    {
 33:       return month;
 34:    }

 36:    /**
 37:       Returns the day of the month of this day
 38:       @return the day of the month
 39:    */
 40:    public int getDate()
 41:    {
 42:       return date;
 43:    }

 45:    /**
 46:       Returns a day that is a certain number of days away from
 47:       this day
 48:       @param n the number of days, can be negative
 49:       @return a day that is n days away from this one
 50:    */
 51:    public Day addDays(int n)
 52:    {
 53:       Day result = this;
 54:       while (n > 0)
 55:       {
 56:          result = result.nextDay();
 57:          n--;
 58:       }
 59:       while (n < 0)
 60:       {
 61:          result = result.previousDay();
 62:          n++;
 63:       }
 64:       return result;
 65:    }

 67:    /**
 68:       Returns the number of days between this day and another
 69:       day
 70:       @param other the other day
 71:       @return the number of days that this day is away from 
 72:       the other (>0 if this day comes later)
 73:    */
 74:    public int daysFrom(Day other)
 75:    {
 76:       int n = 0;
 77:       Day d = this;
 78:       while (d.compareTo(other) > 0)
 79:       {
 80:          d = d.previousDay();
 81:          n++;
 82:       }
 83:       while (d.compareTo(other) < 0)
 84:       {
 85:          d = d.nextDay();
 86:          n--;
 87:       }
 88:       return n;
 89:    }

 91:    /**
 92:       Compares this day with another day.
 93:       @param other the other day
 94:       @return a positive number if this day comes after the
 95:       other day, a negative number if this day comes before
 96:       the other day, and zero if the days are the same
 97:    */
 98:    private int compareTo(Day other)
 99:    {
100:       if (year > other.year) return 1;
101:       if (year < other.year) return -1;
102:       if (month > other.month) return 1;
103:       if (month < other.month) return -1;
104:       return date - other.date;
105:    }

107:    /**
108:       Computes the next day.
109:       @return the day following this day
110:    */
111:    private Day nextDay()
112:    {
113:       int y = year;
114:       int m = month;
115:       int d = date;

117:       if (y == GREGORIAN_START_YEAR
118:          && m == GREGORIAN_START_MONTH
119:          && d == JULIAN_END_DAY)
120:             d = GREGORIAN_START_DAY;
121:       else if (d < daysPerMonth(y, m))
122:          d++;
123:       else
124:       {
125:          d = 1;
126:          m++;
127:          if (m > DECEMBER) 
128:          { 
129:             m = JANUARY; y++; 
130:             if (y == 0) y++;
131:          }
132:       }
133:       return new Day(y, m, d);
134:    }

136:    /**
137:       Computes the previous day.
138:       @return the day preceding this day
139:    */
140:    private Day previousDay()
141:    {
142:       int y = year;
143:       int m = month;
144:       int d = date;

146:       if (y == GREGORIAN_START_YEAR
147:          && m == GREGORIAN_START_MONTH
148:          && d == GREGORIAN_START_DAY)
149:             d = JULIAN_END_DAY;
150:       else if (d > 1)
151:          d--;
152:       else
153:       {        
154:          m--;
155:          if (m < JANUARY) 
156:          {             
157:             m = DECEMBER; y--; 
158:             if (y == 0) y = -1;
159:          }
160:          d = daysPerMonth(y, m);
161:       }
162:       return new Day(y, m, d);
163:    }

165:    /**
166:       Gets the days in a given month
167:       @param y the year
168:       @param m the month
169:       @return the last day in the given month
170:    */
171:    private static int daysPerMonth(int y, int m)
172:    {
173:       int days = DAYS_PER_MONTH[m - 1];
174:       if (m == FEBRUARY && isLeapYear(y)) 
175:          days++;
176:       return days;
177:    }

179:    /**
180:       Tests if a year is a leap year
181:       @param y the year
182:       @return true if y is a leap year
183:    */
184:    private static boolean isLeapYear(int y)
185:    {
186:       if (y % 4 != 0) return false;
187:       if (y < GREGORIAN_START_YEAR) return true;
188:       return (y % 100 != 0) || (y % 400 == 0);
189:    }

191:    private int year;
192:    private int month;
193:    private int date;

195:    private static final int[] DAYS_PER_MONTH 
196:       = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

198:    private static final int GREGORIAN_START_YEAR = 1582;
199:    private static final int GREGORIAN_START_MONTH = 10;
200:    private static final int GREGORIAN_START_DAY = 15;
201:    private static final int JULIAN_END_DAY = 4;

203:    public static final int JANUARY = 1;
204:    public static final int FEBRUARY = 2;
205:    public static final int DECEMBER = 12;
206: }