Ejemplo n.º 1
0
  /**
   * Gets a copy of this date with the specified field set to a new value.
   *
   * <p>If this partial did not previously support the field, the new one will. Contrast this
   * behaviour with {@link #withField(DateTimeFieldType, int)}.
   *
   * <p>For example, if the field type is <code>dayOfMonth</code> then the day would be
   * changed/added in the returned instance.
   *
   * @param fieldType the field type to set, not null
   * @param value the value to set
   * @return a copy of this instance with the field set
   * @throws IllegalArgumentException if the value is null or invalid
   */
  public Partial with(DateTimeFieldType fieldType, int value) {
    if (fieldType == null) {
      throw new IllegalArgumentException("The field type must not be null");
    }
    int index = indexOf(fieldType);
    if (index == -1) {
      DateTimeFieldType[] newTypes = new DateTimeFieldType[iTypes.length + 1];
      int[] newValues = new int[newTypes.length];

      // find correct insertion point to keep largest-smallest order
      int i = 0;
      DurationField unitField = fieldType.getDurationType().getField(iChronology);
      if (unitField.isSupported()) {
        for (; i < iTypes.length; i++) {
          DateTimeFieldType loopType = iTypes[i];
          DurationField loopUnitField = loopType.getDurationType().getField(iChronology);
          if (loopUnitField.isSupported()) {
            int compare = unitField.compareTo(loopUnitField);
            if (compare > 0) {
              break;
            } else if (compare == 0) {
              if (fieldType.getRangeDurationType() == null) {
                break;
              }
              if (loopType.getRangeDurationType() == null) {
                continue;
              }
              DurationField rangeField = fieldType.getRangeDurationType().getField(iChronology);
              DurationField loopRangeField = loopType.getRangeDurationType().getField(iChronology);
              if (rangeField.compareTo(loopRangeField) > 0) {
                break;
              }
            }
          }
        }
      }
      System.arraycopy(iTypes, 0, newTypes, 0, i);
      System.arraycopy(iValues, 0, newValues, 0, i);
      newTypes[i] = fieldType;
      newValues[i] = value;
      System.arraycopy(iTypes, i, newTypes, i + 1, newTypes.length - i - 1);
      System.arraycopy(iValues, i, newValues, i + 1, newValues.length - i - 1);
      // use public constructor to ensure full validation
      // this isn't overly efficient, but is safe
      Partial newPartial = new Partial(newTypes, newValues, iChronology);
      iChronology.validate(newPartial, newValues);
      return newPartial;
    }
    if (value == getValue(index)) {
      return this;
    }
    int[] newValues = getValues();
    newValues = getField(index).set(this, index, newValues, value);
    return new Partial(this, newValues);
  }
Ejemplo n.º 2
0
  /**
   * Constructs a Partial with the specified fields and values. The fields must be specified in the
   * order largest to smallest. For year and weekyear fields with equal duration, year is defined as
   * being larger than weekyear.
   *
   * <p>The constructor uses the specified chronology.
   *
   * @param types the types to create the partial from, not null
   * @param values the values to store, not null
   * @param chronology the chronology, null means ISO
   * @throws IllegalArgumentException if the types or values are invalid
   */
  public Partial(DateTimeFieldType[] types, int[] values, Chronology chronology) {
    super();
    chronology = DateTimeUtils.getChronology(chronology).withUTC();
    iChronology = chronology;
    if (types == null) {
      throw new IllegalArgumentException("Types array must not be null");
    }
    if (values == null) {
      throw new IllegalArgumentException("Values array must not be null");
    }
    if (values.length != types.length) {
      throw new IllegalArgumentException("Values array must be the same length as the types array");
    }
    if (types.length == 0) {
      iTypes = types;
      iValues = values;
      return;
    }
    for (int i = 0; i < types.length; i++) {
      if (types[i] == null) {
        throw new IllegalArgumentException("Types array must not contain null: index " + i);
      }
    }
    DurationField lastUnitField = null;
    for (int i = 0; i < types.length; i++) {
      DateTimeFieldType loopType = types[i];
      DurationField loopUnitField = loopType.getDurationType().getField(iChronology);
      if (i > 0) {
        if (loopUnitField.isSupported() == false) {
          if (lastUnitField.isSupported()) {
            throw new IllegalArgumentException(
                "Types array must be in order largest-smallest: "
                    + types[i - 1].getName()
                    + " < "
                    + loopType.getName());
          } else {
            throw new IllegalArgumentException(
                "Types array must not contain duplicate unsupported: "
                    + types[i - 1].getName()
                    + " and "
                    + loopType.getName());
          }
        }
        int compare = lastUnitField.compareTo(loopUnitField);
        if (compare < 0) {
          throw new IllegalArgumentException(
              "Types array must be in order largest-smallest: "
                  + types[i - 1].getName()
                  + " < "
                  + loopType.getName());
        } else if (compare == 0) {
          if (lastUnitField.equals(loopUnitField)) {
            DurationFieldType lastRangeType = types[i - 1].getRangeDurationType();
            DurationFieldType loopRangeType = loopType.getRangeDurationType();
            if (lastRangeType == null) {
              if (loopRangeType == null) {
                throw new IllegalArgumentException(
                    "Types array must not contain duplicate: "
                        + types[i - 1].getName()
                        + " and "
                        + loopType.getName());
              }
            } else {
              if (loopRangeType == null) {
                throw new IllegalArgumentException(
                    "Types array must be in order largest-smallest: "
                        + types[i - 1].getName()
                        + " < "
                        + loopType.getName());
              }
              DurationField lastRangeField = lastRangeType.getField(iChronology);
              DurationField loopRangeField = loopRangeType.getField(iChronology);
              if (lastRangeField.compareTo(loopRangeField) < 0) {
                throw new IllegalArgumentException(
                    "Types array must be in order largest-smallest: "
                        + types[i - 1].getName()
                        + " < "
                        + loopType.getName());
              }
              if (lastRangeField.compareTo(loopRangeField) == 0) {
                throw new IllegalArgumentException(
                    "Types array must not contain duplicate: "
                        + types[i - 1].getName()
                        + " and "
                        + loopType.getName());
              }
            }
          } else {
            if (lastUnitField.isSupported()
                && lastUnitField.getType() != DurationFieldType.YEARS_TYPE) {
              throw new IllegalArgumentException(
                  "Types array must be in order largest-smallest,"
                      + " for year-based fields, years is defined as being largest: "
                      + types[i - 1].getName()
                      + " < "
                      + loopType.getName());
            }
          }
        }
      }
      lastUnitField = loopUnitField;
    }

    iTypes = (DateTimeFieldType[]) types.clone();
    chronology.validate(this, values);
    iValues = (int[]) values.clone();
  }