code: public final DtEnd getEndDate(final boolean deriveFromDuration) {
          DtEnd dtEnd = getProperty(Property.DTEND);
          // No DTEND? No problem, we'll use the DURATION.
          if (dtEnd == null && deriveFromDuration && getStartDate() != null) {
              final DtStart dtStart = getStartDate();
              final Duration vEventDuration;
              if (getDuration() != null) {
                  vEventDuration = getDuration();
              } else if (dtStart.getDate() instanceof DateTime) {
                  // If "DTSTART" is a DATE-TIME, then the event's duration is zero (see: RFC 5545, 3.6.1 Event Component)
                  vEventDuration = new Duration(java.time.Duration.ZERO);
              } else {
                  // If "DTSTART" is a DATE, then the event's duration is one day (see: RFC 5545, 3.6.1 Event Component)
                  vEventDuration = new Duration(java.time.Duration.ofDays(1));
              }
  
              dtEnd = new DtEnd(Dates.getInstance(Date.from(dtStart.getDate().toInstant().plus(vEventDuration.getDuration())),
                      dtStart.getParameter(Parameter.VALUE)));
              if (dtStart.isUtc()) {
                  dtEnd.setUtc(true);
              } else {
                  dtEnd.setTimeZone(dtStart.getTimeZone());
              }
          }
          return dtEnd;
      }
docs: Convenience method to pull the DTEND out of the property list. If DTEND was not specified, use the DTSTART +
  DURATION to calculate it.
  @param deriveFromDuration specifies whether to derive an end date from the event duration where an end date is
  not found
  @return The end for this VEVENT.