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:       ymdValid = true;
 17:       julianValid = false;
 18:    }

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

 30:    /**
 31:       Returns the month of this day
 32:       @return the month
 33:    */
 34:    public int getMonth()
 35:    {
 36:       ensureYmd();
 37:       return month;
 38:    }

 40:    /**
 41:       Returns the day of the month of this day
 42:       @return the day of the month
 43:    */
 44:    public int getDate()
 45:    {
 46:       ensureYmd();
 47:       return date;
 48:    }

 50:    /**
 51:       Returns a day that is a certain number of days away from
 52:       this day
 53:       @param n the number of days, can be negative
 54:       @return a day that is n days away from this one
 55:    */
 56:    public Day addDays(int n)
 57:    {
 58:       ensureJulian();
 59:       return new Day(julian + n);
 60:    }

 62:    /**
 63:       Returns the number of days between this day and another
 64:       day
 65:       @param other the other day
 66:       @return the number of days that this day is away from 
 67:       the other (>0 if this day comes later)
 68:    */
 69:    public int daysFrom(Day other)
 70:    {
 71:       ensureJulian();
 72:       other.ensureJulian();
 73:       return julian - other.julian;
 74:    }

 76:    private Day(int aJulian)
 77:    {
 78:       julian = aJulian;
 79:       ymdValid = false;
 80:       julianValid = true;
 81:    }

 83:    /**
 84:       Computes the Julian day number of this day if 
 85:       necessary
 86:    */
 87:    private void ensureJulian()
 88:    {  
 89:       if (julianValid) return;
 90:       julian = toJulian(year, month, date);
 91:       julianValid = true;
 92:    }

 94:    /**
 95:       Converts this Julian day mumber to a calendar date if necessary.
 96:    */
 97:    private void ensureYmd()
 98:    {  
 99:       if (ymdValid) return;
100:       int[] ymd = fromJulian(julian);
101:       year = ymd[0];
102:       month = ymd[1];
103:       date = ymd[2];
104:       ymdValid = true;
105:    }

107:    /**
108:       Computes the Julian day number of the given day day.

110:       @param year a year
111:       @param month a month
112:       @param date a day of the month
113:       @return The Julian day number that begins at noon of 
114:       the given day
115:       Positive year signifies CE, negative year BCE. 
116:       Remember that the year after 1 BCE is 1 CE.

118:       A convenient reference point is that May 23, 1968 noon
119:       is Julian day number 2440000.

121:       Julian day number 0 is a Monday.

123:       This algorithm is from Press et al., Numerical Recipes
124:       in C, 2nd ed., Cambridge University Press 1992
125:    */
126:    private static int toJulian(int year, int month, int date)
127:    {  
128:       int jy = year;
129:       if (year < 0) jy++;
130:       int jm = month;
131:       if (month > 2) jm++;
132:       else
133:       {  
134:          jy--;
135:          jm += 13;
136:       }
137:       int jul = (int) (java.lang.Math.floor(365.25 * jy) 
138:             + java.lang.Math.floor(30.6001 * jm) + date + 1720995.0);

140:       int IGREG = 15 + 31 * (10 + 12 * 1582);
141:          // Gregorian Calendar adopted Oct. 15, 1582

143:       if (date + 31 * (month + 12 * year) >= IGREG)
144:          // Change over to Gregorian calendar
145:       {  
146:          int ja = (int) (0.01 * jy);
147:          jul += 2 - ja + (int) (0.25 * ja);
148:       }
149:       return jul;
150:    }

152:    /**
153:       Converts a Julian day number to a calendar date.
154:       
155:       This algorithm is from Press et al., Numerical Recipes
156:       in C, 2nd ed., Cambridge University Press 1992

158:       @param j  the Julian day number
159:       @return an array whose 0 entry is the year, 1 the month,
160:       and 2 the day of the month.
161:    */
162:    private static int[] fromJulian(int j)
163:    {  
164:       int ja = j;
165:    
166:       int JGREG = 2299161;
167:          // The Julian day number of the adoption of the Gregorian calendar    

169:       if (j >= JGREG)
170:          // Cross-over to Gregorian Calendar produces this correction
171:       {  
172:          int jalpha = (int) (((float) (j - 1867216) - 0.25) 
173:              / 36524.25);
174:          ja += 1 + jalpha - (int) (0.25 * jalpha);
175:       }
176:       int jb = ja + 1524;
177:       int jc = (int) (6680.0 + ((float) (jb - 2439870) - 122.1)
178:           / 365.25);
179:       int jd = (int) (365 * jc + (0.25 * jc));
180:       int je = (int) ((jb - jd) / 30.6001);
181:       int date = jb - jd - (int) (30.6001 * je);
182:       int month = je - 1;
183:       if (month > 12) month -= 12;
184:       int year = jc - 4715;
185:       if (month > 2) --year;
186:       if (year <= 0) --year;
187:       return new int[] { year, month, date };
188:    }

190:    private int year;
191:    private int month;
192:    private int date;
193:    private int julian;
194:    private boolean ymdValid;
195:    private boolean julianValid;
196: }