001: public class Day
002: {
003: /**
004: Constructs a day with a given year, month, and day
005: of the Julian/Gregorian calendar. The Julian calendar
006: is used for all days before October 15, 1582
007: @param aYear a year != 0
008: @param aMonth a month between 1 and 12
009: @param aDate a date between 1 and 31
010: */
011: public Day(int aYear, int aMonth, int aDate)
012: {
013: julian = toJulian(aYear, aMonth, aDate);
014: }
015:
016: /**
017: Returns the year of this day
018: @return the year
019: */
020: public int getYear()
021: {
022: return fromJulian(julian)[0];
023: }
024:
025: /**
026: Returns the month of this day
027: @return the month
028: */
029: public int getMonth()
030: {
031: return fromJulian(julian)[1];
032: }
033:
034: /**
035: Returns the day of the month of this day
036: @return the day of the month
037: */
038: public int getDate()
039: {
040: return fromJulian(julian)[2];
041: }
042:
043: /**
044: Returns a day that is a certain number of days away from
045: this day
046: @param n the number of days, can be negative
047: @return a day that is n days away from this one
048: */
049: public Day addDays(int n)
050: {
051: return new Day(julian + n);
052: }
053:
054: /**
055: Returns the number of days between this day and another day.
056: @param other the other day
057: @return the number of days that this day is away from
058: the other (>0 if this day comes later)
059: */
060: public int daysFrom(Day other)
061: {
062: return julian - other.julian;
063: }
064:
065: private Day(int aJulian)
066: {
067: julian = aJulian;
068: }
069:
070: /**
071: Computes the Julian day number of the given day.
072: @param year a year
073: @param month a month
074: @param date a date
075: @return The Julian day number that begins at noon of
076: the given day
077: Positive year signifies CE, negative year BCE.
078: Remember that the year after 1 BCE was 1 CE.
079:
080: A convenient reference point is that May 23, 1968 noon
081: is Julian day number 2440000.
082:
083: Julian day number 0 is a Monday.
084:
085: This algorithm is from Press et al., Numerical Recipes
086: in C, 2nd ed., Cambridge University Press 1992
087: */
088: private static int toJulian(int year, int month, int date)
089: {
090: int jy = year;
091: if (year < 0) jy++;
092: int jm = month;
093: if (month > 2) jm++;
094: else
095: {
096: jy--;
097: jm += 13;
098: }
099: int jul = (int) (java.lang.Math.floor(365.25 * jy)
100: + java.lang.Math.floor(30.6001*jm) + date + 1720995.0);
101:
102: int IGREG = 15 + 31*(10+12*1582);
103: // Gregorian Calendar adopted Oct. 15, 1582
104:
105: if (date + 31 * (month + 12 * year) >= IGREG)
106: // change over to Gregorian calendar
107: {
108: int ja = (int)(0.01 * jy);
109: jul += 2 - ja + (int)(0.25 * ja);
110: }
111: return jul;
112: }
113:
114: /**
115: Converts a Julian day number to a calendar date.
116:
117: This algorithm is from Press et al., Numerical Recipes
118: in C, 2nd ed., Cambridge University Press 1992
119:
120: @param j the Julian day number
121: @return an array whose 0 entry is the year, 1 the month,
122: and 2 the day of the month.
123: */
124: private static int[] fromJulian(int j)
125: {
126: int ja = j;
127:
128: int JGREG = 2299161;
129: /* the Julian day number of the adoption of the Gregorian
130: calendar
131: */
132:
133: if (j >= JGREG)
134: /* cross-over to Gregorian Calendar produces this
135: correction
136: */
137: {
138: int jalpha = (int)(((float)(j - 1867216) - 0.25)
139: / 36524.25);
140: ja += 1 + jalpha - (int)(0.25 * jalpha);
141: }
142: int jb = ja + 1524;
143: int jc = (int)(6680.0 + ((float)(jb-2439870) - 122.1)
144: /365.25);
145: int jd = (int)(365 * jc + (0.25 * jc));
146: int je = (int)((jb - jd)/30.6001);
147: int date = jb - jd - (int)(30.6001 * je);
148: int month = je - 1;
149: if (month > 12) month -= 12;
150: int year = jc - 4715;
151: if (month > 2) --year;
152: if (year <= 0) --year;
153: return new int[] { year, month, date };
154: }
155:
156: private int julian;
157: }
158:
159:
160:
161:
162: