private DateTimeResolutionResult mergeTwoTimePoints()

in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseTimePeriodParser.java [518:634]


    private DateTimeResolutionResult mergeTwoTimePoints(String text, LocalDateTime referenceTime) {
        DateTimeResolutionResult ret = new DateTimeResolutionResult();
        DateTimeParseResult pr1 = null;
        DateTimeParseResult pr2 = null;
        boolean validTimeNumber = false;

        List<ExtractResult> ers = this.config.getTimeExtractor().extract(text, referenceTime);
        if (ers.size() != 2) {
            if (ers.size() == 1) {
                List<ExtractResult> numErs = this.config.getIntegerExtractor().extract(text);
                int erStart = ers.get(0).getStart() != null ? ers.get(0).getStart() : 0;
                int erLength = ers.get(0).getLength() != null ? ers.get(0).getLength() : 0;

                for (ExtractResult num : numErs) {
                    int numStart = num.getStart() != null ? num.getStart() : 0;
                    int numLength = num.getLength() != null ? num.getLength() : 0;
                    int midStrBegin = 0;
                    int midStrEnd = 0;
                    // ending number
                    if (numStart > erStart + erLength) {
                        midStrBegin = erStart + erLength;
                        midStrEnd = numStart - midStrBegin;
                    } else if (numStart + numLength < erStart) {
                        midStrBegin = numStart + numLength;
                        midStrEnd = erStart - midStrBegin;
                    }

                    // check if the middle string between the time point and the valid number is a connect string.
                    String middleStr = text.substring(midStrBegin, midStrBegin + midStrEnd);
                    Optional<Match> tillMatch = Arrays.stream(RegExpUtility.getMatches(this.config.getTillRegex(), middleStr)).findFirst();
                    if (tillMatch.isPresent()) {
                        num.setData(null);
                        num.setType(Constants.SYS_DATETIME_TIME);
                        ers.add(num);
                        validTimeNumber = true;
                        break;
                    }
                }

                ers.sort(Comparator.comparingInt(x -> x.getStart()));
            }

            if (!validTimeNumber) {
                return ret;
            }
        }

        pr1 = this.config.getTimeParser().parse(ers.get(0), referenceTime);
        pr2 = this.config.getTimeParser().parse(ers.get(1), referenceTime);

        if (pr1.getValue() == null || pr2.getValue() == null) {
            return ret;
        }

        String ampmStr1 = ((DateTimeResolutionResult)pr1.getValue()).getComment();
        String ampmStr2 = ((DateTimeResolutionResult)pr2.getValue()).getComment();

        LocalDateTime beginTime = (LocalDateTime)((DateTimeResolutionResult)pr1.getValue()).getFutureValue();
        LocalDateTime endTime = (LocalDateTime)((DateTimeResolutionResult)pr2.getValue()).getFutureValue();

        if (!StringUtility.isNullOrEmpty(ampmStr2) && ampmStr2.endsWith(Constants.Comment_AmPm) &&
                (endTime.compareTo(beginTime) < 1) && endTime.plusHours(Constants.HalfDayHourCount).isAfter(beginTime)) {
            endTime = endTime.plusHours(Constants.HalfDayHourCount);
            ((DateTimeResolutionResult)pr2.getValue()).setFutureValue(endTime);
            pr2.setTimexStr(String.format("T%s", endTime.getHour()));
            if (endTime.getMinute() > 0) {
                pr2.setTimexStr(String.format("%s:%s", pr2.getTimexStr(), endTime.getMinute()));
            }
        }

        if (!StringUtility.isNullOrEmpty(ampmStr1) && ampmStr1.endsWith(Constants.Comment_AmPm) && endTime.isAfter(beginTime.plusHours(Constants.HalfDayHourCount))) {
            beginTime = beginTime.plusHours(Constants.HalfDayHourCount);
            ((DateTimeResolutionResult)pr1.getValue()).setFutureValue(beginTime);
            pr1.setTimexStr(String.format("T%s", beginTime.getHour()));
            if (beginTime.getMinute() > 0) {
                pr1.setTimexStr(String.format("%s:%s", pr1.getTimexStr(), beginTime.getMinute()));
            }
        }

        if (endTime.isBefore(beginTime)) {
            endTime = endTime.plusDays(1);
        }

        long minutes = (Duration.between(beginTime, endTime).toMinutes() % 60);
        long hours = (Duration.between(beginTime, endTime).toHours() % 24);
        ret.setTimex(String.format("(%s,%s,PT", pr1.getTimexStr(), pr2.getTimexStr()));

        if (hours > 0) {
            ret.setTimex(String.format("%s%sH", ret.getTimex(), hours));
        }
        if (minutes > 0) {
            ret.setTimex(String.format("%s%sM", ret.getTimex(), minutes));
        }
        ret.setTimex(ret.getTimex() + ")");

        ret.setFutureValue(new Pair<LocalDateTime, LocalDateTime>(beginTime, endTime));
        ret.setPastValue(new Pair<LocalDateTime, LocalDateTime>(beginTime, endTime));
        ret.setSuccess(true);

        if (!StringUtility.isNullOrEmpty(ampmStr1) && ampmStr1.endsWith(Constants.Comment_AmPm) &&
                !StringUtility.isNullOrEmpty(ampmStr2) && ampmStr2.endsWith(Constants.Comment_AmPm)) {
            ret.setComment(Constants.Comment_AmPm);
        }

        if (((DateTimeResolutionResult)pr1.getValue()).getTimeZoneResolution() != null) {
            ret.setTimeZoneResolution(((DateTimeResolutionResult)pr1.getValue()).getTimeZoneResolution());
        } else if (((DateTimeResolutionResult)pr2.getValue()).getTimeZoneResolution() != null) {
            ret.setTimeZoneResolution(((DateTimeResolutionResult)pr2.getValue()).getTimeZoneResolution());
        }

        List<Object> subDateTimeEntities = new ArrayList<>();
        subDateTimeEntities.add(pr1);
        subDateTimeEntities.add(pr2);
        ret.setSubDateTimeEntities(subDateTimeEntities);

        return ret;
    }