private DateTimeResolutionResult parseImplicitDate()

in Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDateParser.java [153:398]


    private DateTimeResolutionResult parseImplicitDate(String text, LocalDateTime referenceDate) {
        String trimmedText = text.trim();

        DateTimeResolutionResult ret = new DateTimeResolutionResult();

        // handle "on 12"
        Optional<Match> match = Arrays.stream(RegExpUtility.getMatches(this.config.getOnRegex(), this.config.getDateTokenPrefix() + trimmedText)).findFirst();
        if (match.isPresent() && match.get().index == 3 && match.get().length == trimmedText.length()) {
            int month = referenceDate.getMonthValue();
            int year = referenceDate.getYear();
            String dayStr = match.get().getGroup("day").value.toLowerCase();
            int day = this.config.getDayOfMonth().get(dayStr);

            ret.setTimex(DateTimeFormatUtil.luisDate(-1, -1, day));

            LocalDateTime futureDate;
            LocalDateTime pastDate;
            String tryStr = DateTimeFormatUtil.luisDate(year, month, day);
            if (DateUtil.tryParse(tryStr) != null) {
                futureDate = DateUtil.safeCreateFromMinValue(year, month, day);
                pastDate = DateUtil.safeCreateFromMinValue(year, month, day);

                if (futureDate.isBefore(referenceDate)) {
                    futureDate = futureDate.plusMonths(1);
                }

                if (pastDate.isEqual(referenceDate) || pastDate.isAfter(referenceDate)) {
                    pastDate = pastDate.minusMonths(1);
                }
            } else {
                futureDate = DateUtil.safeCreateFromMinValue(year, month + 1, day);
                pastDate = DateUtil.safeCreateFromMinValue(year, month - 1, day);
            }

            ret.setFutureValue(futureDate);
            ret.setPastValue(pastDate);
            ret.setSuccess(true);

            return ret;
        }

        // handle "today", "the day before yesterday"
        ConditionalMatch exactMatch = RegexExtension.matchExact(this.config.getSpecialDayRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            int swift = getSwiftDay(exactMatch.getMatch().get().value);

            LocalDateTime value = referenceDate.toLocalDate().atStartOfDay().plusDays(swift);

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "two days from tomorrow"
        exactMatch = RegexExtension.matchExact(this.config.getSpecialDayWithNumRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {

            int swift = getSwiftDay(exactMatch.getMatch().get().getGroup("day").value);
            List<ExtractResult> numErs = this.config.getIntegerExtractor().extract(trimmedText);
            Object numberParsed = this.config.getNumberParser().parse(numErs.get(0)).getValue();
            int numOfDays = Math.round(((Double)numberParsed).floatValue());

            LocalDateTime value = referenceDate.plusDays(numOfDays + swift);

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "two sundays from now"
        exactMatch = RegexExtension.matchExact(this.config.getRelativeWeekDayRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            List<ExtractResult> numErs = this.config.getIntegerExtractor().extract(trimmedText);
            Object numberParsed = this.config.getNumberParser().parse(numErs.get(0)).getValue();
            int num = Math.round(((Double)numberParsed).floatValue());

            String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
            LocalDateTime value = referenceDate;

            // Check whether the determined day of this week has passed.
            if (value.getDayOfWeek().getValue() > this.config.getDayOfWeek().get(weekdayStr)) {
                num--;
            }

            while (num-- > 0) {
                value = DateUtil.next(value, this.config.getDayOfWeek().get(weekdayStr));
            }

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "next Sunday"
        exactMatch = RegexExtension.matchExact(this.config.getNextRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
            LocalDateTime value = DateUtil.next(referenceDate, this.config.getDayOfWeek().get(weekdayStr));

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "this Friday"
        exactMatch = RegexExtension.matchExact(this.config.getThisRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
            LocalDateTime value = DateUtil.thisDate(referenceDate, this.config.getDayOfWeek().get(weekdayStr));

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "last Friday", "last mon"
        exactMatch = RegexExtension.matchExact(this.config.getLastRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
            LocalDateTime value = DateUtil.last(referenceDate, this.config.getDayOfWeek().get(weekdayStr));

            ret.setTimex(DateTimeFormatUtil.luisDate(value));
            ret.setFutureValue(value);
            ret.setPastValue(value);
            ret.setSuccess(true);

            return ret;
        }

        // handle "Friday"
        exactMatch = RegexExtension.matchExact(this.config.getWeekDayRegex(), trimmedText, true);

        if (exactMatch.getSuccess()) {
            String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
            int weekDay = this.config.getDayOfWeek().get(weekdayStr);
            LocalDateTime value = DateUtil.thisDate(referenceDate, this.config.getDayOfWeek().get(weekdayStr));

            if (weekDay == 0) {
                weekDay = 7;
            }

            if (weekDay < referenceDate.getDayOfWeek().getValue()) {
                value = DateUtil.next(referenceDate, weekDay);
            }

            ret.setTimex("XXXX-WXX-" + weekDay);
            LocalDateTime futureDate = value;
            LocalDateTime pastDate = value;
            if (futureDate.isBefore(referenceDate)) {
                futureDate = futureDate.plusDays(7);
            }

            if (pastDate.isEqual(referenceDate) || pastDate.isAfter(referenceDate)) {
                pastDate = pastDate.minusDays(7);
            }

            ret.setFutureValue(futureDate);
            ret.setPastValue(pastDate);
            ret.setSuccess(true);

            return ret;
        }

        // handle "for the 27th."
        match = Arrays.stream(RegExpUtility.getMatches(this.config.getForTheRegex(), text)).findFirst();
        if (match.isPresent()) {
            int day;
            int month = referenceDate.getMonthValue();
            int year = referenceDate.getYear();
            String dayStr = match.get().getGroup("DayOfMonth").value.toLowerCase();

            int start = match.get().getGroup("DayOfMonth").index;
            int length = match.get().getGroup("DayOfMonth").length;

            // create a extract comments which content ordinal string of text
            ExtractResult er = new ExtractResult(start, length, dayStr, null, null);

            Object numberParsed = this.config.getNumberParser().parse(er).getValue();
            day = Math.round(((Double)numberParsed).floatValue());

            ret.setTimex(DateTimeFormatUtil.luisDate(-1, -1, day));

            LocalDateTime futureDate;
            String tryStr = DateTimeFormatUtil.luisDate(year, month, day);

            if (DateUtil.tryParse(tryStr) != null) {
                futureDate = DateUtil.safeCreateFromMinValue(year, month, day);
            } else {
                futureDate = DateUtil.safeCreateFromMinValue(year, month + 1, day);
            }

            ret.setFutureValue(futureDate);
            ret.setPastValue(ret.getFutureValue());
            ret.setSuccess(true);

            return ret;
        }

        // handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
        match = Arrays.stream(RegExpUtility.getMatches(this.config.getWeekDayAndDayOfMonthRegex(), text)).findFirst();
        if (match.isPresent()) {
            int month = referenceDate.getMonthValue();
            int year = referenceDate.getYear();
            String dayStr = match.get().getGroup("DayOfMonth").value.toLowerCase();

            int start = match.get().getGroup("DayOfMonth").index;
            int length = match.get().getGroup("DayOfMonth").length;

            // create a extract comments which content ordinal string of text
            ExtractResult erTmp = new ExtractResult(start, length, dayStr, null, null);

            Object numberParsed = this.config.getNumberParser().parse(erTmp).getValue();
            int day = Math.round(((Double)numberParsed).floatValue());

            // the validity of the phrase is guaranteed in the Date Extractor
            ret.setTimex(DateTimeFormatUtil.luisDate(year, month, day));
            ret.setFutureValue(LocalDateTime.of(year, month, day, 0, 0));
            ret.setPastValue(LocalDateTime.of(year, month, day, 0, 0));
            ret.setSuccess(true);

            return ret;
        }

        return ret;
    }