code: public T toDateTime(DateTime dateTime) {
      try {
        D dateObj = dateClass.newInstance();
        PropertyUtils.setProperty(dateObj, "year", dateTime.getYear());
        PropertyUtils.setProperty(dateObj, "month", dateTime.getMonthOfYear());
        PropertyUtils.setProperty(dateObj, "day", dateTime.getDayOfMonth());
  
        T dateTimeObj = dateTimeClass.newInstance();
        PropertyUtils.setProperty(dateTimeObj, "date", dateObj);
        PropertyUtils.setProperty(dateTimeObj, "hour", dateTime.getHourOfDay());
        PropertyUtils.setProperty(dateTimeObj, "minute", dateTime.getMinuteOfHour());
        PropertyUtils.setProperty(dateTimeObj, "second", dateTime.getSecondOfMinute());
        // Starting in v201811, timeZoneID was renamed to timeZoneId
        if (PropertyUtils.isWriteable(dateTimeObj, "timeZoneID")) {
          PropertyUtils.setProperty(
              dateTimeObj, "timeZoneID", dateTime.getZone().toTimeZone().getID());
        } else {
          PropertyUtils.setProperty(
              dateTimeObj, "timeZoneId", dateTime.getZone().toTimeZone().getID());
        }
  
        return dateTimeObj;
      } catch (InstantiationException e) {
        throw new IllegalStateException("Could not instantiate class.", e);
      } catch (IllegalAccessException e) {
        throw new IllegalStateException("Could not instantiate class.", e);
      } catch (InvocationTargetException e) {
        throw new IllegalStateException("Could not set field.", e);
      } catch (NoSuchMethodException e) {
        throw new IllegalStateException("Could not set field.", e);
      }
    }
docs: Converts a {@code DateTime} object to an API date time preserving the
  time zone.