private DateTimeResolutionResult mergeDateAndTime()

in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDateTimeParser.java [101:234]


    private DateTimeResolutionResult mergeDateAndTime(String text, LocalDateTime reference) {
        DateTimeResolutionResult result = new DateTimeResolutionResult();
        List<ExtractResult> ersDate = config.getDateExtractor().extract(text, reference);
        if (ersDate.isEmpty()) {
            ersDate = config.getDateExtractor().extract(config.getTokenBeforeDate() + text, reference);
            if (ersDate.size() == 1) {
                int newStart = ersDate.get(0).getStart() - config.getTokenBeforeDate().length();
                ersDate.get(0).setStart(newStart);
                ersDate.set(0, ersDate.get(0));
            } else {
                return result;
            }
        } else {
            // This is to understand if there is an ambiguous token in the text. For some
            // languages (e.g. spanish),
            // the same word could mean different things (e.g a time in the day or an
            // specific day).
            if (config.containsAmbiguousToken(text, ersDate.get(0).getText())) {
                return result;
            }
        }

        List<ExtractResult> ersTime = config.getTimeExtractor().extract(text, reference);
        if (ersTime.isEmpty()) {
            // Here we filter out "morning, afternoon, night..." time entities
            ersTime = config.getTimeExtractor().extract(config.getTokenBeforeTime() + text, reference);
            if (ersTime.size() == 1) {
                int newStart = ersTime.get(0).getStart() - config.getTokenBeforeTime().length();
                ersTime.get(0).setStart(newStart);
                ersTime.set(0, ersTime.get(0));
            } else if (ersTime.isEmpty()) {
                // check whether there is a number being used as a time point
                boolean hasTimeNumber = false;
                List<ExtractResult> numErs = config.getIntegerExtractor().extract(text);
                if (!numErs.isEmpty() && ersDate.size() == 1) {
                    for (ExtractResult num : numErs) {
                        int middleBegin = ersDate.get(0).getStart() + ersDate.get(0).getLength();
                        int middleEnd = num.getStart();
                        if (middleBegin > middleEnd) {
                            continue;
                        }

                        String middleStr = text.substring(middleBegin, middleEnd).trim().toLowerCase();
                        Optional<Match> match = Arrays
                                .stream(RegExpUtility.getMatches(config.getDateNumberConnectorRegex(), middleStr))
                                .findFirst();
                        if (StringUtility.isNullOrEmpty(middleStr) || match.isPresent()) {
                            num.setType(Constants.SYS_DATETIME_TIME);
                            ersTime.add(num);
                            hasTimeNumber = true;
                        }
                    }
                }

                if (!hasTimeNumber) {
                    return result;
                }
            }
        }

        // Handle cases like "Oct. 5 in the afternoon at 7:00";
        // in this case "5 in the afternoon" will be extracted as a Time entity
        int correctTimeIdx = 0;
        while (correctTimeIdx < ersTime.size() && ersTime.get(correctTimeIdx).isOverlap(ersDate.get(0))) {
            correctTimeIdx++;
        }

        if (correctTimeIdx >= ersTime.size()) {
            return result;
        }

        DateTimeParseResult prDate = config.getDateParser().parse(ersDate.get(0), reference);
        DateTimeParseResult prTime = config.getTimeParser().parse(ersTime.get(correctTimeIdx), reference);

        if (prDate.getValue() == null || prTime.getValue() == null) {
            return result;
        }

        LocalDateTime futureDate = (LocalDateTime)((DateTimeResolutionResult)prDate.getValue()).getFutureValue();
        LocalDateTime pastDate = (LocalDateTime)((DateTimeResolutionResult)prDate.getValue()).getPastValue();
        LocalDateTime time = (LocalDateTime)((DateTimeResolutionResult)prTime.getValue()).getPastValue();

        int hour = time.getHour();
        int min = time.getMinute();
        int sec = time.getSecond();

        // Handle morning, afternoon
        if (RegExpUtility.getMatches(config.getPMTimeRegex(), text).length != 0 && withinAfternoonHours(hour)) {
            hour += Constants.HalfDayHourCount;
        } else if (RegExpUtility.getMatches(config.getAMTimeRegex(), text).length != 0 &&
                withinMorningHoursAndNoon(hour, min, sec)) {
            hour -= Constants.HalfDayHourCount;
        }

        String timeStr = prTime.getTimexStr();
        if (timeStr.endsWith(Constants.Comment_AmPm)) {
            timeStr = timeStr.substring(0, timeStr.length() - 4);
        }

        timeStr = String.format("T%02d%s", hour, timeStr.substring(3));
        result.setTimex(prDate.getTimexStr() + timeStr);
        DateTimeResolutionResult val = (DateTimeResolutionResult)prTime.getValue();
        if (hour <= Constants.HalfDayHourCount && RegExpUtility.getMatches(config.getPMTimeRegex(), text).length == 0 &&
                RegExpUtility.getMatches(config.getAMTimeRegex(), text).length == 0 &&
                !StringUtility.isNullOrEmpty(val.getComment())) {
            result.setComment(Constants.Comment_AmPm);
        }

        result.setFutureValue(DateUtil.safeCreateFromMinValue(futureDate.getYear(), futureDate.getMonthValue(),
                futureDate.getDayOfMonth(), hour, min, sec));
        result.setPastValue(DateUtil.safeCreateFromMinValue(pastDate.getYear(), pastDate.getMonthValue(),
                pastDate.getDayOfMonth(), hour, min, sec));

        result.setSuccess(true);

        // Change the value of time object
        prTime.setTimexStr(timeStr);
        if (!StringUtility.isNullOrEmpty(result.getComment())) {
            DateTimeResolutionResult newValue = (DateTimeResolutionResult)prTime.getValue();
            newValue.setComment(result.getComment().equals(Constants.Comment_AmPm) ? Constants.Comment_AmPm : "");
            prTime.setValue(newValue);
            prTime.setTimexStr(timeStr);
        }

        // Add the date and time object in case we want to split them
        List<Object> entities = new ArrayList<>();
        entities.add(prDate);
        entities.add(prTime);
        result.setSubDateTimeEntities(entities);

        result.setTimeZoneResolution(((DateTimeResolutionResult)prTime.getValue()).getTimeZoneResolution());

        return result;
    }