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.DateTime; 23 import org.joda.time.DateTimeConstants; 24 import org.joda.time.DateTimeField; 25 import org.joda.time.DateTimeZone; 26 import org.joda.time.field.SkipDateTimeField; 27 28 51 public final class CopticChronology extends BasicFixedMonthChronology { 52 53 54 private static final long serialVersionUID = -5972804258688333942L; 55 56 60 public static final int AM = DateTimeConstants.CE; 61 62 63 private static final DateTimeField ERA_FIELD = new BasicSingleEraDateTimeField("AM"); 64 65 66 private static final int MIN_YEAR = -292269337; 67 68 69 private static final int MAX_YEAR = 292272708; 70 71 72 private static final Map cCache = new HashMap (); 73 74 75 private static final CopticChronology INSTANCE_UTC; 76 static { 77 INSTANCE_UTC = getInstance(DateTimeZone.UTC); 79 } 80 81 88 public static CopticChronology getInstanceUTC() { 89 return INSTANCE_UTC; 90 } 91 92 97 public static CopticChronology getInstance() { 98 return getInstance(DateTimeZone.getDefault(), 4); 99 } 100 101 107 public static CopticChronology getInstance(DateTimeZone zone) { 108 return getInstance(zone, 4); 109 } 110 111 118 public static CopticChronology getInstance(DateTimeZone zone, int minDaysInFirstWeek) { 119 if (zone == null) { 120 zone = DateTimeZone.getDefault(); 121 } 122 CopticChronology chrono; 123 synchronized (cCache) { 124 CopticChronology[] chronos = (CopticChronology[]) cCache.get(zone); 125 if (chronos == null) { 126 chronos = new CopticChronology[7]; 127 cCache.put(zone, chronos); 128 } 129 try { 130 chrono = chronos[minDaysInFirstWeek - 1]; 131 } catch (ArrayIndexOutOfBoundsException e) { 132 throw new IllegalArgumentException 133 ("Invalid min days in first week: " + minDaysInFirstWeek); 134 } 135 if (chrono == null) { 136 if (zone == DateTimeZone.UTC) { 137 chrono = new CopticChronology(null, null, minDaysInFirstWeek); 139 DateTime lowerLimit = new DateTime(1, 1, 1, 0, 0, 0, 0, chrono); 141 chrono = new CopticChronology 142 (LimitChronology.getInstance(chrono, lowerLimit, null), 143 null, minDaysInFirstWeek); 144 } else { 145 chrono = getInstance(DateTimeZone.UTC, minDaysInFirstWeek); 146 chrono = new CopticChronology 147 (ZonedChronology.getInstance(chrono, zone), null, minDaysInFirstWeek); 148 } 149 chronos[minDaysInFirstWeek - 1] = chrono; 150 } 151 } 152 return chrono; 153 } 154 155 160 CopticChronology(Chronology base, Object param, int minDaysInFirstWeek) { 161 super(base, param, minDaysInFirstWeek); 162 } 163 164 167 private Object readResolve() { 168 Chronology base = getBase(); 169 int minDays = getMinimumDaysInFirstWeek(); 170 minDays = (minDays == 0 ? 4 : minDays); return base == null ? 172 getInstance(DateTimeZone.UTC, minDays) : 173 getInstance(base.getZone(), minDays); 174 } 175 176 183 public Chronology withUTC() { 184 return INSTANCE_UTC; 185 } 186 187 193 public Chronology withZone(DateTimeZone zone) { 194 if (zone == null) { 195 zone = DateTimeZone.getDefault(); 196 } 197 if (zone == getZone()) { 198 return this; 199 } 200 return getInstance(zone); 201 } 202 203 long calculateFirstDayOfYearMillis(int year) { 205 209 int relativeYear = year - 1687; 210 int leapYears; 211 if (relativeYear <= 0) { 212 leapYears = (relativeYear + 3) >> 2; 215 } else { 216 leapYears = relativeYear >> 2; 217 if (!isLeapYear(year)) { 219 leapYears++; 220 } 221 } 222 223 long millis = (relativeYear * 365L + leapYears) 224 * (long)DateTimeConstants.MILLIS_PER_DAY; 225 226 228 return millis + (365L - 112) * DateTimeConstants.MILLIS_PER_DAY; 229 } 230 231 int getMinYear() { 233 return MIN_YEAR; 234 } 235 236 int getMaxYear() { 238 return MAX_YEAR; 239 } 240 241 long getApproxMillisAtEpochDividedByTwo() { 243 return (1686L * MILLIS_PER_YEAR + 112L * DateTimeConstants.MILLIS_PER_DAY) / 2; 244 } 245 246 protected void assemble(Fields fields) { 248 if (getBase() == null) { 249 super.assemble(fields); 250 251 fields.year = new SkipDateTimeField(this, fields.year); 253 fields.weekyear = new SkipDateTimeField(this, fields.weekyear); 254 255 fields.era = ERA_FIELD; 256 fields.monthOfYear = new BasicMonthOfYearDateTimeField(this, 13); 257 fields.months = fields.monthOfYear.getDurationField(); 258 } 259 } 260 261 } 262 | Popular Tags |