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: