public int daysBetween(final DateHolder other) {
    final DateHolder from, to;
    if (this.getTimeInMillis() < other.getTimeInMillis()) {
      from = this;
      to = other;
    } else {
      from = other;
      to = this;
    }
    int result = 0;
    final int toYear = to.getYear();
    final DateHolder dh = new DateHolder(from.getDate());

    int endlessLoopProtection = 0;
    while (dh.getYear() < toYear) {
      final int fromDay = dh.getDayOfYear();
      dh.setMonth(Calendar.DECEMBER);
      dh.setDayOfMonth(31);
      result += dh.getDayOfYear() - fromDay + 1;
      dh.add(Calendar.DAY_OF_MONTH, 1);
      if (++endlessLoopProtection > 5000) {
        throw new IllegalArgumentException("Days between doesn's support more than 5000 years");
      }
    }
    result += to.getDayOfYear() - dh.getDayOfYear();
    if (this.getTimeInMillis() < other.getTimeInMillis()) {
      return result;
    } else {
      return -result;
    }
  }
  private void calculate() {
    DateHolder dateHolder = new DateHolder(cal, DatePrecision.DAY);
    year = dateHolder.getYear();
    month = dateHolder.getMonth();
    dateHolder.setBeginOfMonth();
    begin = dateHolder.getDate(); // Storing begin of month.
    dateHolder.setEndOfMonth();
    end = dateHolder.getDate(); // Storing end of month.
    dateHolder.setDate(begin); // reset to begin of month
    dateHolder.computeTime();
    dateHolder.setBeginOfWeek(); // get first week (with days of previous month)

    weeks = new ArrayList<WeekHolder>();
    do {
      WeekHolder week = new WeekHolder(dateHolder.getCalendar(), month);
      weeks.add(week);
      dateHolder.add(Calendar.WEEK_OF_YEAR, 1);
    } while (dateHolder.getMonth() == month);
  }
 /**
  * Has the given date the same day? The given date will be converted into a calendar (clone from
  * this) with same time zone.
  *
  * @param date
  * @return
  */
 public boolean isSameDay(final DateHolder date) {
   return getYear() == date.getYear() && getDayOfYear() == date.getDayOfYear();
 }