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; 
130:             y++; 
131:             if (y == 0) y++;
132:          }
133:       }
134:       return new Day(y, m, d);
135:    }

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

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

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

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

193:    private int year;
194:    private int month;
195:    private int date;

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

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

205:    private static final int JANUARY = 1;
206:    private static final int FEBRUARY = 2;
207:    private static final int DECEMBER = 12;
208: }