Exemple #1
0
  /**
   * Adds a Duration to this Date/Time type as defined in <a
   * href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">Adding Duration to
   * dateTimes (W3C XML Schema, part 2 appendix E).</a> This version is using the algorithm defined
   * in the document from W3C, next version may optimize it.
   *
   * @param duration the duration to add
   */
  public void addDuration(Duration duration) {
    int temp = 0;
    int carry = 0;
    int sign = (duration.isNegative()) ? -1 : 1;
    // don't use getter methods but use direct field access for dateTime
    // in order to have the behaviour defined in the Recommendation document
    // Months
    try {
      temp = _month + sign * duration.getMonth();
      carry = fQuotient(temp - 1, 12);
      temp = modulo(temp - 1, 12) + 1;
      this.setMonth((short) temp);
    } catch (OperationNotSupportedException e) {
      // if there is no Month field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (!((this instanceof Time) || (this instanceof GYear) || (this instanceof GDay))) throw e;
    }
    // Years
    try {
      temp = _century * 100 + _year + sign * duration.getYear() + carry;
      short century = (short) (temp / 100);
      temp = temp % 100;
      this.setCentury(century);
      this.setYear((short) temp);
    } catch (OperationNotSupportedException e) {
      // if there is no Year field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (!((this instanceof Time) || (this instanceof GMonthDay))) throw e;
    }
    // Seconds
    try {
      temp = _second + sign * duration.getSeconds();
      carry = fQuotient(temp, 60);
      temp = modulo(temp, 60);
      this.setSecond((short) temp, this.getMilli());
    } catch (OperationNotSupportedException e) {
      // if there is no Second field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (this instanceof Time) throw e;
    }
    // Minutes
    try {
      temp = _minute + sign * duration.getMinute() + carry;
      carry = fQuotient(temp, 60);
      temp = modulo(temp, 60);
      this.setMinute((short) temp);
    } catch (OperationNotSupportedException e) {
      // if there is no Minute field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (this instanceof Time) throw e;
    }
    // Hours
    try {
      temp = _hour + sign * duration.getHour() + carry;
      carry = fQuotient(temp, 24);
      temp = modulo(temp, 24);
      this.setHour((short) temp);
    } catch (OperationNotSupportedException e) {
      // if there is no Hour field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (this instanceof Time) throw e;
    }
    // Days
    try {
      int maxDay = maxDayInMonthFor(_century, _year, _month);
      int tempDay = (_day > maxDay) ? maxDay : _day;
      // how to handle day < 1????this makes sense only if we create a new
      // dateTime type (rare situation)
      tempDay = tempDay + sign * duration.getDay() + carry;
      while (true) {
        if (tempDay < 1) {
          tempDay = (short) (tempDay + maxDayInMonthFor(_century, _year, _month - 1));
          this.setDay((short) tempDay);
          carry = -1;
        } else if (tempDay > maxDay) {
          tempDay = (short) (tempDay - (short) maxDay);
          carry = 1;
        } else break;
        try {
          temp = _month + carry;
          this.setMonth((short) (modulo(temp - 1, 12) + 1));
          temp = fQuotient(temp - 1, 12);
          temp = this.getCentury() * 100 + this.getYear() + temp;
          short century = (short) (temp / 100);
          temp = temp % 100;
          this.setCentury(century);
          this.setYear((short) temp);
        } catch (OperationNotSupportedException e) {
          // --if there is no Year field in the date/time datatypes
          // --we do nothing else we throw a runTime exception
          if (!((this instanceof Time) || (this instanceof GMonthDay))) throw e;
        }
      }
      this.setDay((short) tempDay);

    } catch (OperationNotSupportedException e) {
      // if there is no Month field in the date/time datatypes
      // we do nothing else we throw a runTime exception
      if (!((this instanceof Time) || (this instanceof GYearMonth) || (this instanceof GMonth)))
        throw e;
    }
  } // addDuration