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 aDayOfMonth a day of the month between 1 and 31
 10     */
 11     public Day(int aYear, int aMonth, int aDayOfMonth)
 12     {
 13        julian = toJulian(aYear, aMonth, aDayOfMonth);
 14     }
 15  
 16     /**
 17        Returns the year of this day
 18        @return the year
 19     */
 20     public int getYear()
 21     {
 22        return fromJulian(julian)[0];
 23     }
 24  
 25     /**
 26        Returns the month of this day
 27        @return the month
 28     */
 29     public int getMonthValue()
 30     {
 31        return fromJulian(julian)[1];
 32     }
 33  
 34     /**
 35        Returns the day of the month of this day
 36        @return the day of the month
 37     */
 38     public int getDayOfMonth()
 39     {
 40        return fromJulian(julian)[2];
 41     }
 42  
 43     /**
 44        Returns a day that is a certain number of days away from
 45        this day
 46        @param n the number of days, can be negative
 47        @return a day that is n days away from this one
 48     */
 49     public Day plusDays(int n)
 50     {
 51        return new Day(julian + n);
 52     }
 53  
 54     /**
 55        Returns the number of days between this day and another day.
 56        @param other the other day
 57        @return the number of days that this day is away from 
 58        the other (>0 if this day comes later)
 59     */
 60     public int daysFrom(Day other)
 61     {
 62        return julian - other.julian;
 63     }
 64  
 65     private Day(int aJulian)
 66     {
 67        julian = aJulian;
 68     }
 69  
 70     /**
 71        Computes the Julian day number of the given day.
 72        @param year a year
 73        @param month a month
 74        @param date a day of the month
 75        @return The Julian day number that begins at noon of 
 76        the given day
 77        Positive year signifies CE, negative year BCE. 
 78        Remember that the year after 1 BCE was 1 CE.
 79  
 80        A convenient reference point is that May 23, 1968 noon
 81        is Julian day number 2440000.
 82  
 83        Julian day number 0 is a Monday.
 84  
 85        This algorithm is from Press et al., Numerical Recipes
 86        in C, 2nd ed., Cambridge University Press 1992
 87     */
 88     private static int toJulian(int year, int month, int date)
 89     {  
 90        int jy = year;
 91        if (year < 0) jy++;
 92        int jm = month;
 93        if (month > 2) jm++;
 94        else
 95        {  
 96           jy--;
 97           jm += 13;
 98        }
 99        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 calendar    
130  
131        if (j >= JGREG)
132           // Cross-over to Gregorian Calendar produces this correction
133        {  
134           int jalpha = (int) (((float) (j - 1867216) - 0.25) 
135               / 36524.25);
136           ja += 1 + jalpha - (int) (0.25 * jalpha);
137        }
138        int jb = ja + 1524;
139        int jc = (int) (6680.0 + ((float) (jb - 2439870) - 122.1)
140            / 365.25);
141        int jd = (int) (365 * jc + (0.25 * jc));
142        int je = (int) ((jb - jd) / 30.6001);
143        int date = jb - jd - (int) (30.6001 * je);
144        int month = je - 1;
145        if (month > 12) month -= 12;
146        int year = jc - 4715;
147        if (month > 2) --year;
148        if (year <= 0) --year;
149        return new int[] { year, month, date };
150     }
151  
152     private int julian;
153  }
154  
155  
156  
157  
158