    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: