1 16 package org.joda.time.chrono; 17 18 import java.util.HashMap ; 19 import java.util.Map ; 20 21 import org.joda.time.Chronology; 22 import org.joda.time.DateTimeConstants; 23 import org.joda.time.DateTimeFieldType; 24 import org.joda.time.DateTimeZone; 25 import org.joda.time.IllegalFieldValueException; 26 import org.joda.time.field.SkipDateTimeField; 27 28 50 public final class JulianChronology extends BasicGJChronology { 51 52 53 private static final long serialVersionUID = -8731039522547897247L; 54 55 private static final long MILLIS_PER_YEAR = 56 (long) (365.25 * DateTimeConstants.MILLIS_PER_DAY); 57 58 private static final long MILLIS_PER_MONTH = 59 (long) (365.25 * DateTimeConstants.MILLIS_PER_DAY / 12); 60 61 62 private static final int MIN_YEAR = -292269054; 63 64 65 private static final int MAX_YEAR = 292272992; 66 67 68 private static final JulianChronology INSTANCE_UTC; 69 70 71 private static final Map cCache = new HashMap (); 72 73 static { 74 INSTANCE_UTC = getInstance(DateTimeZone.UTC); 75 } 76 77 static int adjustYearForSet(int year) { 78 if (year <= 0) { 79 if (year == 0) { 80 throw new IllegalFieldValueException 81 (DateTimeFieldType.year(), new Integer (year), null, null); 82 } 83 year++; 84 } 85 return year; 86 } 87 88 94 public static JulianChronology getInstanceUTC() { 95 return INSTANCE_UTC; 96 } 97 98 103 public static JulianChronology getInstance() { 104 return getInstance(DateTimeZone.getDefault(), 4); 105 } 106 107 113 public static JulianChronology getInstance(DateTimeZone zone) { 114 return getInstance(zone, 4); 115 } 116 117 124 public static JulianChronology getInstance(DateTimeZone zone, int minDaysInFirstWeek) { 125 if (zone == null) { 126 zone = DateTimeZone.getDefault(); 127 } 128 JulianChronology chrono; 129 synchronized (cCache) { 130 JulianChronology[] chronos = (JulianChronology[]) cCache.get(zone); 131 if (chronos == null) { 132 chronos = new JulianChronology[7]; 133 cCache.put(zone, chronos); 134 } 135 try { 136 chrono = chronos[minDaysInFirstWeek - 1]; 137 } catch (ArrayIndexOutOfBoundsException e) { 138 throw new IllegalArgumentException 139 ("Invalid min days in first week: " + minDaysInFirstWeek); 140 } 141 if (chrono == null) { 142 if (zone == DateTimeZone.UTC) { 143 chrono = new JulianChronology(null, null, minDaysInFirstWeek); 144 } else { 145 chrono = getInstance(DateTimeZone.UTC, minDaysInFirstWeek); 146 chrono = new JulianChronology 147 (ZonedChronology.getInstance(chrono, zone), null, minDaysInFirstWeek); 148 } 149 chronos[minDaysInFirstWeek - 1] = chrono; 150 } 151 } 152 return chrono; 153 } 154 155 158 161 JulianChronology(Chronology base, Object param, int minDaysInFirstWeek) { 162 super(base, param, minDaysInFirstWeek); 163 } 164 165 168 private Object readResolve() { 169 Chronology base = getBase(); 170 int minDays = getMinimumDaysInFirstWeek(); 171 minDays = (minDays == 0 ? 4 : minDays); return base == null ? 173 getInstance(DateTimeZone.UTC, minDays) : 174 getInstance(base.getZone(), minDays); 175 } 176 177 184 public Chronology withUTC() { 185 return INSTANCE_UTC; 186 } 187 188 194 public Chronology withZone(DateTimeZone zone) { 195 if (zone == null) { 196 zone = DateTimeZone.getDefault(); 197 } 198 if (zone == getZone()) { 199 return this; 200 } 201 return getInstance(zone); 202 } 203 204 long getDateMidnightMillis(int year, int monthOfYear, int dayOfMonth) 205 throws IllegalArgumentException 206 { 207 return super.getDateMidnightMillis(adjustYearForSet(year), monthOfYear, dayOfMonth); 208 } 209 210 boolean isLeapYear(int year) { 211 return (year & 3) == 0; 212 } 213 214 long calculateFirstDayOfYearMillis(int year) { 215 219 int relativeYear = year - 1968; 220 int leapYears; 221 if (relativeYear <= 0) { 222 leapYears = (relativeYear + 3) >> 2; 225 } else { 226 leapYears = relativeYear >> 2; 227 if (!isLeapYear(year)) { 229 leapYears++; 230 } 231 } 232 233 long millis = (relativeYear * 365L + leapYears) * (long)DateTimeConstants.MILLIS_PER_DAY; 234 235 237 return millis - (366L + 352) * DateTimeConstants.MILLIS_PER_DAY; 238 } 239 240 int getMinYear() { 241 return MIN_YEAR; 242 } 243 244 int getMaxYear() { 245 return MAX_YEAR; 246 } 247 248 long getAverageMillisPerYear() { 249 return MILLIS_PER_YEAR; 250 } 251 252 long getAverageMillisPerYearDividedByTwo() { 253 return MILLIS_PER_YEAR / 2; 254 } 255 256 long getAverageMillisPerMonth() { 257 return MILLIS_PER_MONTH; 258 } 259 260 long getApproxMillisAtEpochDividedByTwo() { 261 return (1969L * MILLIS_PER_YEAR + 352L * DateTimeConstants.MILLIS_PER_DAY) / 2; 262 } 263 264 protected void assemble(Fields fields) { 265 if (getBase() == null) { 266 super.assemble(fields); 267 fields.year = new SkipDateTimeField(this, fields.year); 269 fields.weekyear = new SkipDateTimeField(this, fields.weekyear); 270 } 271 } 272 273 } 274 | Popular Tags |