public class Day
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: }