Program: 50633
Project: 50633
Buggy source:
/** 
 * calcDate uses all the field available so far to fill a Date object. For those information that is not provided, the existing value in 'date' will be kept. Ambiguous year will be resolved after the date/time values are resolved. If the strict option is set to true, calcDate will calculate certain invalid dates by wrapping around as needed. For example, February 30 will wrap to March 2.
 * @param date The Date object being filled. Its value should be set to anacceptable default before pass in to this method
 * @param strict true to be strict when parsing
 * @return true if successful, otherwise false.
 */
public boolean calcDate(SSDate date,boolean strict){
  if (this.era == 0 && this.year > 0) {
    this.year=-(this.year - 1);
  }
  if (this.year > Integer.MIN_VALUE) {
    date.setYear(this.year - JS_START_YEAR);
  }
  int orgDayOfMonth=date.getDate();
  date.setDate(1);
  if (this.month >= 0) {
    date.setMonth(this.month);
  }
  if (this.dayOfMonth >= 0) {
    date.setDate(this.dayOfMonth);
  }
 else   if (this.month >= 0) {
    SSDate tmp=new SSDate(date.getYear(),date.getMonth(),35);
    int daysInCurrentMonth=35 - tmp.getDate();
    date.setDate(Math.min(daysInCurrentMonth,orgDayOfMonth));
  }
 else {
    date.setDate(orgDayOfMonth);
  }
  if (this.hours < 0) {
    this.hours=date.getHours();
  }
  if (this.ampm > 0) {
    if (this.hours < 12) {
      this.hours+=12;
    }
  }
  date.setHours(this.hours);
  if (this.minutes >= 0) {
    date.setMinutes(this.minutes);
  }
  if (this.seconds >= 0) {
    date.setSeconds(this.seconds);
  }
  if (this.milliseconds >= 0) {
    date.setTime(date.getTime() / 1000 * 1000 + this.milliseconds);
  }
  if (strict) {
    if ((this.year > Integer.MIN_VALUE) && ((this.year - JS_START_YEAR) != date.getYear())) {
      return false;
    }
    if ((this.month >= 0) && (this.month != date.getMonth())) {
      return false;
    }
    if ((this.dayOfMonth >= 0) && (this.dayOfMonth != date.getDate())) {
      return false;
    }
    if (this.hours >= 24) {
      return false;
    }
    if (this.minutes >= 60) {
      return false;
    }
    if (this.seconds >= 60) {
      return false;
    }
    if (this.milliseconds >= 1000) {
      return false;
    }
  }
  if (this.ambiguousYear) {
    SSDate defaultCenturyStart=new SSDate();
    defaultCenturyStart.setYear(defaultCenturyStart.getYear() - 80);
    if (date.before(defaultCenturyStart)) {
      date.setYear(defaultCenturyStart.getYear() + 100);
    }
  }
  if (this.dayOfWeek >= 0) {
    if (this.dayOfMonth == -1) {
      int adjustment=(7 + this.dayOfWeek - date.getDay()) % 7;
      if (adjustment > 3) {
        adjustment-=7;
      }
      int orgMonth=date.getMonth();
      date.setDate(date.getDate() + adjustment);
      if (date.getMonth() != orgMonth) {
        date.setDate(date.getDate() + (adjustment > 0 ? -7 : 7));
      }
    }
 else {
      if (date.getDay() != this.dayOfWeek) {
        return false;
      }
    }
  }
  if (this.tzOffset > Integer.MIN_VALUE) {
    date.setTimezoneOffset(this.tzOffset);
    date.setTime(date.getTime());
  }
  return true;
}

Fixed version (ground truth):
/** 
 * calcDate uses all the field available so far to fill a Date object. For those information that is not provided, the existing value in 'date' will be kept. Ambiguous year will be resolved after the date/time values are resolved. If the strict option is set to true, calcDate will calculate certain invalid dates by wrapping around as needed. For example, February 30 will wrap to March 2.
 * @param date The Date object being filled. Its value should be set to anacceptable default before pass in to this method
 * @param strict true to be strict when parsing
 * @return true if successful, otherwise false.
 */
public boolean calcDate(SSDate date,boolean strict){
  if (this.era == 0 && this.year > 0) {
    this.year=-(this.year - 1);
  }
  if (this.year > Integer.MIN_VALUE) {
    date.setYear(this.year - JS_START_YEAR);
  }
  int orgDayOfMonth=date.getDate();
  date.setDate(1);
  if (this.month >= 0) {
    date.setMonth(this.month);
  }
  if (this.dayOfMonth >= 0) {
    date.setDate(this.dayOfMonth);
  }
 else   if (this.month >= 0) {
    SSDate tmp=new SSDate(date.getYear(),date.getMonth(),35);
    int daysInCurrentMonth=35 - tmp.getDate();
    date.setDate(Math.min(daysInCurrentMonth,orgDayOfMonth));
  }
 else {
    date.setDate(orgDayOfMonth);
  }
  if (this.hours < 0) {
    this.hours=date.getHours();
  }
  if (this.ampm > 0) {
    if (this.hours < 12) {
      this.hours+=12;
    }
  }
  date.setHours(this.hours);
  if (this.minutes >= 0) {
    date.setMinutes(this.minutes);
  }
  if (this.seconds >= 0) {
    date.setSeconds(this.seconds);
  }
  if (this.milliseconds >= 0) {
    date.setTime(date.getTime() / 1000 * 1000 + this.milliseconds);
  }
  if (strict) {
    if ((this.year > Integer.MIN_VALUE) && ((this.year - JS_START_YEAR) != date.getYear())) {
      return false;
    }
    if ((this.month >= 0) && (this.month != date.getMonth())) {
      return false;
    }
    if ((this.dayOfMonth >= 0) && (this.dayOfMonth != date.getDate())) {
      return false;
    }
    if (this.hours >= 24) {
      return false;
    }
    if (this.minutes >= 60) {
      return false;
    }
    if (this.seconds >= 60) {
      return false;
    }
    if (this.milliseconds >= 1000) {
      return false;
    }
  }
  if (this.ambiguousYear) {
    SSDate defaultCenturyStart=new SSDate();
    defaultCenturyStart.setYear(defaultCenturyStart.getYear() - 80);
    if (date.before(defaultCenturyStart)) {
      date.setYear(defaultCenturyStart.getYear() + 100);
    }
  }
  if (this.dayOfWeek >= 0) {
    if (this.dayOfMonth == -1) {
      int adjustment=(7 + this.dayOfWeek - date.getDay()) % 7;
      if (adjustment > 3) {
        adjustment-=7;
      }
      int orgMonth=date.getMonth();
      date.setDate(date.getDate() + adjustment);
      if (date.getMonth() != orgMonth) {
        date.setDate(date.getDate() + (adjustment > 0 ? -7 : 7));
      }
    }
 else {
      if (date.getDay() != this.dayOfWeek) {
        return false;
      }
    }
  }
  if (this.tzOffset > Integer.MIN_VALUE) {
    long timeStamp=date.getTime();
    date.setTimezoneOffset(this.tzOffset);
    date.setTime(timeStamp);
  }
  return true;
}