public DateTimeParseResult parse()

in Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java [72:286]


    public DateTimeParseResult parse(ExtractResult er, LocalDateTime reference) {

        DateTimeParseResult pr = null;

        String originText = er.getText();
        if (this.config.getOptions().match(DateTimeOptions.EnablePreview)) {
            String newText = MatchingUtil.preProcessTextRemoveSuperfluousWords(er.getText(), config.getSuperfluousWordMatcher()).getText();
            int newLength = er.getLength() + newText.length() - originText.length();
            er = new ExtractResult(er.getStart(), newLength, newText, er.getType(), er.getData(), er.getMetadata());
        }

        // Push, save the MOD string
        boolean hasBefore = false;
        boolean hasAfter = false;
        boolean hasSince = false;
        boolean hasAround = false;
        boolean hasYearAfter = false;

        // "InclusiveModifier" means MOD should include the start/end time
        // For example, cases like "on or later than", "earlier than or in" have inclusive modifier
        boolean hasInclusiveModifier = false;
        String modStr = "";

        if (er.getMetadata() != null && er.getMetadata().getHasMod()) {
            ConditionalMatch beforeMatch = RegexExtension.matchBegin(config.getBeforeRegex(), er.getText(), true);
            ConditionalMatch afterMatch = RegexExtension.matchBegin(config.getAfterRegex(), er.getText(), true);
            ConditionalMatch sinceMatch = RegexExtension.matchBegin(config.getSinceRegex(), er.getText(), true);
            ConditionalMatch aroundMatch = RegexExtension.matchBegin(config.getAroundRegex(), er.getText(), true);

            if (beforeMatch.getSuccess()) {
                hasBefore = true;
                er.setStart(er.getStart() + beforeMatch.getMatch().get().length);
                er.setLength(er.getLength() - beforeMatch.getMatch().get().length);
                er.setText(er.getText().substring(beforeMatch.getMatch().get().length));
                modStr = beforeMatch.getMatch().get().value;

                if (!StringUtility.isNullOrEmpty(beforeMatch.getMatch().get().getGroup("include").value)) {
                    hasInclusiveModifier = true;
                }
            } else if (afterMatch.getSuccess()) {
                hasAfter = true;
                er.setStart(er.getStart() + afterMatch.getMatch().get().length);
                er.setLength(er.getLength() - afterMatch.getMatch().get().length);
                er.setText(er.getText().substring(afterMatch.getMatch().get().length));
                modStr = afterMatch.getMatch().get().value;

                if (!StringUtility.isNullOrEmpty(afterMatch.getMatch().get().getGroup("include").value)) {
                    hasInclusiveModifier = true;
                }
            } else if (sinceMatch.getSuccess()) {
                hasSince = true;
                er.setStart(er.getStart() + sinceMatch.getMatch().get().length);
                er.setLength(er.getLength() - sinceMatch.getMatch().get().length);
                er.setText(er.getText().substring(sinceMatch.getMatch().get().length));
                modStr = sinceMatch.getMatch().get().value;
            } else if (aroundMatch.getSuccess()) {
                hasAround = true;
                er.setStart(er.getStart() + aroundMatch.getMatch().get().length);
                er.setLength(er.getLength() - aroundMatch.getMatch().get().length);
                er.setText(er.getText().substring(aroundMatch.getMatch().get().length));
                modStr = aroundMatch.getMatch().get().value;
            } else if ((er.getType().equals(Constants.SYS_DATETIME_DATEPERIOD) &&
                Arrays.stream(RegExpUtility.getMatches(config.getYearRegex(), er.getText())).findFirst().isPresent()) ||
                (er.getType().equals(Constants.SYS_DATETIME_DATE)) || (er.getType().equals(Constants.SYS_DATETIME_TIME))) {
                // This has to be put at the end of the if, or cases like "before 2012" and "after 2012" would fall into this
                // 2012 or after/above, 3 pm or later
                ConditionalMatch match = RegexExtension.matchEnd(config.getSuffixAfterRegex(), er.getText(), true);
                if (match.getSuccess()) {
                    hasYearAfter = true;
                    er.setLength(er.getLength() - match.getMatch().get().length);
                    er.setText(er.getLength() > 0 ? er.getText().substring(0, er.getLength()) : "");
                    modStr = match.getMatch().get().value;
                }
            }
        }

        if (er.getType().equals(Constants.SYS_DATETIME_DATE)) {
            if (er.getMetadata() != null && er.getMetadata().getIsHoliday()) {
                pr = config.getHolidayParser().parse(er, reference);
            } else {
                pr = this.config.getDateParser().parse(er, reference);
            }
        } else if (er.getType().equals(Constants.SYS_DATETIME_TIME)) {
            pr = this.config.getTimeParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_DATETIME)) {
            pr = this.config.getDateTimeParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_DATEPERIOD)) {
            pr = this.config.getDatePeriodParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_TIMEPERIOD)) {
            pr = this.config.getTimePeriodParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_DATETIMEPERIOD)) {
            pr = this.config.getDateTimePeriodParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_DURATION)) {
            pr = this.config.getDurationParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_SET)) {
            pr = this.config.getGetParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_DATETIMEALT)) {
            pr = this.config.getDateTimeAltParser().parse(er, reference);
        } else if (er.getType().equals(Constants.SYS_DATETIME_TIMEZONE)) {
            if (config.getOptions().match(DateTimeOptions.EnablePreview)) {
                pr = this.config.getTimeZoneParser().parse(er, reference);
            }
        } else {
            return null;
        }

        if (pr == null) {
            return null;
        }

        // Pop, restore the MOD string
        if (hasBefore && pr != null && pr.getValue() != null) {

            pr.setStart(pr.getStart() - modStr.length());
            pr.setText(modStr + pr.getText());
            pr.setLength(pr.getLength() + modStr.length());

            DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();

            if (!hasInclusiveModifier) {
                val.setMod(combineMod(val.getMod(), Constants.BEFORE_MOD));
            } else {
                val.setMod(combineMod(val.getMod(), Constants.UNTIL_MOD));
            }

            pr.setValue(val);
        }

        if (hasAfter && pr != null && pr.getValue() != null) {

            pr.setStart(pr.getStart() - modStr.length());
            pr.setText(modStr + pr.getText());
            pr.setLength(pr.getLength() + modStr.length());

            DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();

            if (!hasInclusiveModifier) {
                val.setMod(combineMod(val.getMod(), Constants.AFTER_MOD));
            } else {
                val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
            }

            pr.setValue(val);
        }

        if (hasSince && pr != null && pr.getValue() != null) {

            pr.setStart(pr.getStart() - modStr.length());
            pr.setText(modStr + pr.getText());
            pr.setLength(pr.getLength() + modStr.length());

            DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
            val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
            pr.setValue(val);
        }

        if (hasAround && pr != null && pr.getValue() != null) {

            pr.setStart(pr.getStart() - modStr.length());
            pr.setText(modStr + pr.getText());
            pr.setLength(pr.getLength() + modStr.length());

            DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
            val.setMod(combineMod(val.getMod(), Constants.APPROX_MOD));
            pr.setValue(val);
        }

        if (hasYearAfter && pr != null && pr.getValue() != null) {

            pr.setText(pr.getText() + modStr);
            pr.setLength(pr.getLength() + modStr.length());

            DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
            val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
            pr.setValue(val);
            hasSince = true;
        }

        // For cases like "3 pm or later on Monday"
        if (pr != null && pr.getValue() != null && pr.getType().equals(Constants.SYS_DATETIME_DATETIME)) {
            Optional<Match> match = Arrays.stream(RegExpUtility.getMatches(config.getSuffixAfterRegex(), pr.getText())).findFirst();
            if (match.isPresent() && match.get().index != 0) {
                DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
                val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
                pr.setValue(val);
                hasSince = true;
            }
        }

        if (config.getOptions().match(DateTimeOptions.SplitDateAndTime) && pr != null && pr.getValue() != null &&
                ((DateTimeResolutionResult)pr.getValue()).getSubDateTimeEntities() != null) {
            pr.setValue(dateTimeResolutionForSplit(pr));
        } else {
            boolean hasModifier = hasBefore || hasAfter || hasSince;
            if (pr.getValue() != null) {
                ((DateTimeResolutionResult)pr.getValue()).setHasRangeChangingMod(hasModifier);
            }

            pr = setParseResult(pr, hasModifier);
        }

        // In this version, ExperimentalMode only cope with the "IncludePeriodEnd" case
        if (this.config.getOptions().match(DateTimeOptions.ExperimentalMode)) {
            if (pr.getMetadata() != null && pr.getMetadata().getIsPossiblyIncludePeriodEnd()) {
                pr = setInclusivePeriodEnd(pr);
            }
        }

        if (this.config.getOptions().match(DateTimeOptions.EnablePreview)) {
            int prLength = pr.getLength() + originText.length() - pr.getText().length();
            pr = new DateTimeParseResult(pr.getStart(), prLength, originText, pr.getType(), pr.getData(), pr.getValue(), pr.getResolutionStr(), pr.getTimexStr());
        }

        return pr;
    }