public DateTime changeTimeZone(TimeZone aFromTimeZone, TimeZone aToTimeZone){
    DateTime result = null;
    ensureHasYearMonthDay();
    if (unitsAllAbsent(Unit.HOUR)){
      throw new IllegalArgumentException("DateTime does not include the hour. Cannot change the time zone if no hour is present.");
    }
    Calendar fromDate = new GregorianCalendar(aFromTimeZone);
    fromDate.set(Calendar.YEAR, getYear());
    fromDate.set(Calendar.MONTH, getMonth()-1);
    fromDate.set(Calendar.DAY_OF_MONTH, getDay());
    fromDate.set(Calendar.HOUR_OF_DAY, getHour());
    if(getMinute() != null) {
      fromDate.set(Calendar.MINUTE, getMinute());
    }
    else {
      fromDate.set(Calendar.MINUTE, 0);
    }
    //other items zeroed out here, since they don't matter for time zone calculations
    fromDate.set(Calendar.SECOND, 0);
    fromDate.set(Calendar.MILLISECOND, 0);

    //millisecond precision is OK here, since the seconds/nanoseconds are not part of the calc
    Calendar toDate = new GregorianCalendar(aToTimeZone);
    toDate.setTimeInMillis(fromDate.getTimeInMillis());
    //needed if this date has hour, but no minute (bit of an oddball case) :
    Integer minute = getMinute() != null ? toDate.get(Calendar.MINUTE) : null;
    result = new DateTime(
      toDate.get(Calendar.YEAR), toDate.get(Calendar.MONTH) + 1, toDate.get(Calendar.DAY_OF_MONTH), 
      toDate.get(Calendar.HOUR_OF_DAY), minute, getSecond(), getNanoseconds() 
    );
    return result;
  }