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.DateTimeZone; 24 25 45 public final class GregorianChronology extends BasicGJChronology { 46 47 48 private static final long serialVersionUID = -861407383323710522L; 49 50 private static final long MILLIS_PER_YEAR = 51 (long) (365.2425 * DateTimeConstants.MILLIS_PER_DAY); 52 53 private static final long MILLIS_PER_MONTH = 54 (long) (365.2425 * DateTimeConstants.MILLIS_PER_DAY / 12); 55 56 private static final int DAYS_0000_TO_1970 = 719527; 57 58 59 private static final int MIN_YEAR = -292275054; 60 61 62 private static final int MAX_YEAR = 292278993; 63 64 65 private static final GregorianChronology INSTANCE_UTC; 66 67 68 private static final Map cCache = new HashMap (); 69 70 static { 71 INSTANCE_UTC = getInstance(DateTimeZone.UTC); 72 } 73 74 80 public static GregorianChronology getInstanceUTC() { 81 return INSTANCE_UTC; 82 } 83 84 89 public static GregorianChronology getInstance() { 90 return getInstance(DateTimeZone.getDefault(), 4); 91 } 92 93 99 public static GregorianChronology getInstance(DateTimeZone zone) { 100 return getInstance(zone, 4); 101 } 102 103 110 public static GregorianChronology getInstance(DateTimeZone zone, int minDaysInFirstWeek) { 111 if (zone == null) { 112 zone = DateTimeZone.getDefault(); 113 } 114 GregorianChronology chrono; 115 synchronized (cCache) { 116 GregorianChronology[] chronos = (GregorianChronology[]) cCache.get(zone); 117 if (chronos == null) { 118 chronos = new GregorianChronology[7]; 119 cCache.put(zone, chronos); 120 } 121 try { 122 chrono = chronos[minDaysInFirstWeek - 1]; 123 } catch (ArrayIndexOutOfBoundsException e) { 124 throw new IllegalArgumentException 125 ("Invalid min days in first week: " + minDaysInFirstWeek); 126 } 127 if (chrono == null) { 128 if (zone == DateTimeZone.UTC) { 129 chrono = new GregorianChronology(null, null, minDaysInFirstWeek); 130 } else { 131 chrono = getInstance(DateTimeZone.UTC, minDaysInFirstWeek); 132 chrono = new GregorianChronology 133 (ZonedChronology.getInstance(chrono, zone), null, minDaysInFirstWeek); 134 } 135 chronos[minDaysInFirstWeek - 1] = chrono; 136 } 137 } 138 return chrono; 139 } 140 141 144 147 private GregorianChronology(Chronology base, Object param, int minDaysInFirstWeek) { 148 super(base, param, minDaysInFirstWeek); 149 } 150 151 154 private Object readResolve() { 155 Chronology base = getBase(); 156 int minDays = getMinimumDaysInFirstWeek(); 157 minDays = (minDays == 0 ? 4 : minDays); return base == null ? 159 getInstance(DateTimeZone.UTC, minDays) : 160 getInstance(base.getZone(), minDays); 161 } 162 163 170 public Chronology withUTC() { 171 return INSTANCE_UTC; 172 } 173 174 180 public Chronology withZone(DateTimeZone zone) { 181 if (zone == null) { 182 zone = DateTimeZone.getDefault(); 183 } 184 if (zone == getZone()) { 185 return this; 186 } 187 return getInstance(zone); 188 } 189 190 protected void assemble(Fields fields) { 191 if (getBase() == null) { 192 super.assemble(fields); 193 } 194 } 195 196 boolean isLeapYear(int year) { 197 return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0); 198 } 199 200 long calculateFirstDayOfYearMillis(int year) { 201 int leapYears = year / 100; 203 if (year < 0) { 204 leapYears = ((year + 3) >> 2) - leapYears + ((leapYears + 3) >> 2) - 1; 210 } else { 211 leapYears = (year >> 2) - leapYears + (leapYears >> 2); 212 if (isLeapYear(year)) { 213 leapYears--; 214 } 215 } 216 217 return (year * 365L + (leapYears - DAYS_0000_TO_1970)) * DateTimeConstants.MILLIS_PER_DAY; 218 } 219 220 int getMinYear() { 221 return MIN_YEAR; 222 } 223 224 int getMaxYear() { 225 return MAX_YEAR; 226 } 227 228 long getAverageMillisPerYear() { 229 return MILLIS_PER_YEAR; 230 } 231 232 long getAverageMillisPerYearDividedByTwo() { 233 return MILLIS_PER_YEAR / 2; 234 } 235 236 long getAverageMillisPerMonth() { 237 return MILLIS_PER_MONTH; 238 } 239 240 long getApproxMillisAtEpochDividedByTwo() { 241 return (1970L * MILLIS_PER_YEAR) / 2; 242 } 243 244 } 245 | Popular Tags |