/** * Creates a new instance representing the number of complete standard length units * in the specified period. * <p> * This factory method converts all fields from the period to hours using standardised * durations for each field. Only those fields which have a precise duration in * the ISO UTC chronology can be converted. * <ul> * <li>One week consists of 7 days. * <li>One day consists of 24 hours. * <li>One hour consists of 60 minutes. * <li>One minute consists of 60 seconds. * <li>One second consists of 1000 milliseconds. * </ul> * Months and Years are imprecise and periods containing these values cannot be converted. * * @param period the period to get the number of hours from, must not be null * @param millisPerUnit the number of milliseconds in one standard unit of this period * @throws IllegalArgumentException if the period contains imprecise duration values */ protected static int standardPeriodIn(ReadablePeriod period, long millisPerUnit) { if (period == null) { return 0; } Chronology iso = ISOChronology.getInstanceUTC(); long duration = 0L; for (int i = 0; i < period.size(); i++) { int value = period.getValue(i); if (value != 0) { DurationField field = period.getFieldType(i).getField(iso); if (field.isPrecise() == false) { throw new IllegalArgumentException( "Cannot convert period to duration as " + field.getName() + " is not precise in the period " + period); } duration = FieldUtils.safeAdd(duration, FieldUtils.safeMultiply(field.getUnitMillis(), value)); } } return FieldUtils.safeToInt(duration / millisPerUnit); }
/** * Gets an instance of UnsupportedDateTimeField for a specific named field. * Names should be of standard format, such as 'monthOfYear' or 'hourOfDay'. * The returned instance is cached. * * @param type the type to obtain * @return the instance * @throws IllegalArgumentException if durationField is null */ public static synchronized UnsupportedDateTimeField getInstance( DateTimeFieldType type, DurationField durationField) { UnsupportedDateTimeField field; if (cCache == null) { cCache = new HashMap<DateTimeFieldType, UnsupportedDateTimeField>(7); field = null; } else { field = cCache.get(type); if (field != null && field.getDurationField() != durationField) { field = null; } } if (field == null) { field = new UnsupportedDateTimeField(type, durationField); cCache.put(type, field); } return field; }
/** * Constructor. * * @param field the field to wrap, like "year()". * @param type the field type this field actually uses * @param divisor divisor, such as 100 years in a century * @throws IllegalArgumentException if divisor is less than two */ public RemainderDateTimeField(DateTimeField field, DateTimeFieldType type, int divisor) { super(field, type); if (divisor < 2) { throw new IllegalArgumentException("The divisor must be at least 2"); } DurationField rangeField = field.getDurationField(); if (rangeField == null) { iRangeField = null; } else { iRangeField = new ScaledDurationField( rangeField, type.getRangeDurationType(), divisor); } iDivisor = divisor; }
/** * Constructor. * * @param type the field type this field uses * @param unit precise unit duration, like "seconds()". * @param range precise range duration, preferably a multiple of the unit, * like "minutes()". * @throws IllegalArgumentException if either duration field is imprecise * @throws IllegalArgumentException if unit milliseconds is less than one * or effective value range is less than two. */ public PreciseDateTimeField(DateTimeFieldType type, DurationField unit, DurationField range) { super(type, unit); if (!range.isPrecise()) { throw new IllegalArgumentException("Range duration field must be precise"); } long rangeMillis = range.getUnitMillis(); iRange = (int)(rangeMillis / getUnitMillis()); if (iRange < 2) { throw new IllegalArgumentException("The effective range must be at least 2"); } iRangeField = range; }
ZonedDateTimeField(DateTimeField field, DateTimeZone zone, DurationField durationField, DurationField rangeDurationField, DurationField leapDurationField) { super(field.getType()); if (!field.isSupported()) { throw new IllegalArgumentException(); } iField = field; iZone = zone; iDurationField = durationField; iTimeField = useTimeArithmetic(durationField); iRangeDurationField = rangeDurationField; iLeapDurationField = leapDurationField; }
/** * @param julianField field from the chronology used before the cutover instant * @param gregorianField field from the chronology used at and after the cutover * @param cutoverMillis the millis of the cutover * @param convertByWeekyear */ CutoverField(DateTimeField julianField, DateTimeField gregorianField, long cutoverMillis, boolean convertByWeekyear) { super(gregorianField.getType()); iJulianField = julianField; iGregorianField = gregorianField; iCutover = cutoverMillis; iConvertByWeekyear = convertByWeekyear; // Although average length of Julian and Gregorian years differ, // use the Gregorian duration field because it is more accurate. iDurationField = gregorianField.getDurationField(); DurationField rangeField = gregorianField.getRangeDurationField(); if (rangeField == null) { rangeField = julianField.getRangeDurationField(); } iRangeDurationField = rangeField; }
/** * Gets the values of a period from an interval. * * @param period the period instant to use * @param duration the duration to query * @return the values of the period extracted from the duration */ public int[] get(ReadablePeriod period, long duration) { int size = period.size(); int[] values = new int[size]; if (duration != 0) { long current = 0; for (int i = 0; i < size; i++) { DurationField field = period.getFieldType(i).getField(this); if (field.isPrecise()) { int value = field.getDifference(duration, current); current = field.add(current, value); values[i] = value; } } } return values; }
/** * Constructor. * * @param field the base field * @param type the field type to use */ protected DelegatedDurationField(DurationField field, DurationFieldType type) { super(); if (field == null) { throw new IllegalArgumentException("The field must not be null"); } iField = field; iType = (type == null ? field.getType() : type); }
public int compareTo(DurationField otherField) { long otherMillis = otherField.getUnitMillis(); long thisMillis = getUnitMillis(); // cannot do (thisMillis - otherMillis) as can overflow if (thisMillis == otherMillis) { return 0; } if (thisMillis < otherMillis) { return -1; } else { return 1; } }
/** * Constructor. * * @param field the field to wrap, like "year()". * @param type the field type this field will actually use * @param divisor divisor, such as 100 years in a century * @throws IllegalArgumentException if divisor is less than two */ public DividedDateTimeField(DateTimeField field, DateTimeFieldType type, int divisor) { super(field, type); if (divisor < 2) { throw new IllegalArgumentException("The divisor must be at least 2"); } DurationField unitField = field.getDurationField(); if (unitField == null) { iDurationField = null; } else { iDurationField = new ScaledDurationField( unitField, type.getDurationType(), divisor); } iDivisor = divisor; int i = field.getMinimumValue(); int min = (i >= 0) ? i / divisor : ((i + 1) / divisor - 1); int j = field.getMaximumValue(); int max = (j >= 0) ? j / divisor : ((j + 1) / divisor - 1); iMin = min; iMax = max; }
/** * Constructor. * * @param type the field type * @param unit precise unit duration, like "days()". * @throws IllegalArgumentException if duration field is imprecise * @throws IllegalArgumentException if unit milliseconds is less than one */ public PreciseDurationDateTimeField(DateTimeFieldType type, DurationField unit) { super(type); if (!unit.isPrecise()) { throw new IllegalArgumentException("Unit duration field must be precise"); } iUnitMillis = unit.getUnitMillis(); if (iUnitMillis < 1) { throw new IllegalArgumentException("The unit milliseconds must be at least 1"); } iUnitField = unit; }
static int compareReverse(DurationField a, DurationField b) { if (a == null || !a.isSupported()) { if (b == null || !b.isSupported()) { return 0; } return -1; } if (b == null || !b.isSupported()) { return 1; } return -a.compareTo(b); }
private DurationField convertField(DurationField field, HashMap<Object, Object> converted) { if (field == null || !field.isSupported()) { return field; } if (converted.containsKey(field)) { return (DurationField)converted.get(field); } LimitDurationField limitField = new LimitDurationField(field); converted.put(field, limitField); return limitField; }
LimitDateTimeField(DateTimeField field, DurationField durationField, DurationField rangeDurationField, DurationField leapDurationField) { super(field, field.getType()); iDurationField = durationField; iRangeDurationField = rangeDurationField; iLeapDurationField = leapDurationField; }
private DurationField convertField(DurationField field, HashMap<Object, Object> converted) { if (field == null || !field.isSupported()) { return field; } if (converted.containsKey(field)) { return (DurationField)converted.get(field); } ZonedDurationField zonedField = new ZonedDurationField(field, getZone()); converted.put(field, zonedField); return zonedField; }
ZonedDurationField(DurationField field, DateTimeZone zone) { super(field.getType()); if (!field.isSupported()) { throw new IllegalArgumentException(); } iField = field; iTimeField = useTimeArithmetic(field); iZone = zone; }
/** * Uses a shared duration field rather than creating a new one. * * @param durationField shared duration field */ ImpreciseCutoverField(DateTimeField julianField, DateTimeField gregorianField, DurationField durationField, long cutoverMillis, boolean convertByWeekyear) { super(julianField, gregorianField, cutoverMillis, convertByWeekyear); if (durationField == null) { durationField = new LinkedDurationField(iDurationField, this); } iDurationField = durationField; }
/** * Gets the values of a period from an interval. * * @param period the period instant to use * @param startInstant the start instant of an interval to query * @param endInstant the start instant of an interval to query * @return the values of the period extracted from the interval */ public int[] get(ReadablePeriod period, long startInstant, long endInstant) { int size = period.size(); int[] values = new int[size]; if (startInstant != endInstant) { for (int i = 0; i < size; i++) { DurationField field = period.getFieldType(i).getField(this); int value = field.getDifference(endInstant, startInstant); startInstant = field.add(startInstant, value); values[i] = value; } } return values; }
@Override public DurationField getField(Chronology chronology) { return new ScaledDurationField(chronology.months(), Quarters, 3); }
@Override public DurationField getRangeDurationField() { return this.chron.months(); }
@Override public final DurationField months() { return this.monthDuration; }
@Override public DurationField getRangeDurationField() { return this.chron.years(); }
public YearField(DurationField yearDuration) { super(DateTimeFieldType.year(), yearDuration); }
/** Returns null: the field has no range */ @Override public DurationField getRangeDurationField() { return null; }
@Override public final DurationField millis() { return millisecondDuration; }
@Override public final DurationField seconds() { return secondDuration; }
@Override public final DurationField minutes() { return minuteDuration; }
@Override public final DurationField hours() { return hourDuration; }
@Override public final DurationField halfdays() { return halfdayDuration; }
/** Each day has exactly the same length: there is no daylight saving */ @Override public final DurationField days() { return dayDuration; }
/** Each week has 7 days */ @Override public final DurationField weeks() { return weekDuration; }
@Override public abstract DurationField months();
@Override public final DurationField years() { return this.yearDuration; }
@Override public final DurationField centuries() { return this.centuryDuration; }
public OneBasedPreciseDateTimeField(DateTimeFieldType fieldType, DurationField unit, DurationField range) { super(fieldType, unit, range); }
/** Each month has exactly 30 days */ @Override public DurationField months() { return this.monthDuration; }
public int compareTo(DurationField durationField) { return iField.compareTo(durationField); }
public final DurationField getDurationField() { return iDurationField; }
/** * Returns a scaled version of the wrapped field's unit duration field. */ public DurationField getRangeDurationField() { return iRangeField; }