private DateTimeResolutionResult parseOneWordPeriod()

in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDatePeriodParser.java [550:833]


    private DateTimeResolutionResult parseOneWordPeriod(String text, LocalDateTime referenceDate) {

        DateTimeResolutionResult ret = new DateTimeResolutionResult();
        int year = referenceDate.getYear();
        int month = referenceDate.getMonthValue();
        int futureYear = year;
        int pastYear = year;
        boolean earlyPrefix = false;
        boolean latePrefix = false;
        boolean midPrefix = false;
        boolean isRef = false;

        boolean earlierPrefix = false;
        boolean laterPrefix = false;

        String trimmedText = text.trim().toLowerCase();
        ConditionalMatch match = RegexExtension.matchExact(this.config.getOneWordPeriodRegex(), trimmedText, true);

        if (!match.getSuccess()) {
            match = RegexExtension.matchExact(this.config.getLaterEarlyPeriodRegex(), trimmedText, true);
        }

        // For cases "that week|month|year"
        if (!match.getSuccess()) {
            match = RegexExtension.matchExact(this.config.getReferenceDatePeriodRegex(), trimmedText, true);
            isRef = true;
            ret.setMod(Constants.REF_UNDEF_MOD);
        }

        if (match.getSuccess()) {
            if (!match.getMatch().get().getGroup("EarlyPrefix").value.equals("")) {
                earlyPrefix = true;
                trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
                ret.setMod(Constants.EARLY_MOD);
            } else if (!match.getMatch().get().getGroup("LatePrefix").value.equals("")) {
                latePrefix = true;
                trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
                ret.setMod(Constants.LATE_MOD);
            } else if (!match.getMatch().get().getGroup("MidPrefix").value.equals("")) {
                midPrefix = true;
                trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
                ret.setMod(Constants.MID_MOD);
            }

            int swift = 0;
            String monthStr = match.getMatch().get().getGroup("month").value;
            if (!StringUtility.isNullOrEmpty(monthStr)) {
                swift = this.config.getSwiftYear(trimmedText);
            } else {
                swift = this.config.getSwiftDayOrMonth(trimmedText);
            }

            // Handle the abbreviation of DatePeriod, e.g., 'eoy(end of year)', the behavior of 'eoy' should be the same as 'end of year'
            Optional<Match> unspecificEndOfRangeMatch = Arrays.stream(RegExpUtility.getMatches(config.getUnspecificEndOfRangeRegex(), match.getMatch().get().value)).findFirst();
            if (unspecificEndOfRangeMatch.isPresent()) {
                latePrefix = true;
                trimmedText = match.getMatch().get().value;
                ret.setMod(Constants.LATE_MOD);
            }

            if (!match.getMatch().get().getGroup("RelEarly").value.equals("")) {
                earlierPrefix = true;
                if (isPresent(swift)) {
                    ret.setMod(null);
                }
            } else if (!match.getMatch().get().getGroup("RelLate").value.equals("")) {
                laterPrefix = true;
                if (isPresent(swift)) {
                    ret.setMod(null);
                }
            }

            if (this.config.isYearToDate(trimmedText)) {
                ret.setTimex(String.format("%04d", referenceDate.getYear()));
                ret.setFutureValue(new Pair<>(
                        DateUtil.safeCreateFromMinValue(referenceDate.getYear(), 1, 1), referenceDate));
                ret.setPastValue(new Pair<>(
                        DateUtil.safeCreateFromMinValue(referenceDate.getYear(), 1, 1), referenceDate));

                ret.setSuccess(true);
                return ret;
            }

            if (this.config.isMonthToDate(trimmedText)) {
                ret.setTimex(String.format("%04d-%02d", referenceDate.getYear(), referenceDate.getMonthValue()));
                ret.setFutureValue(new Pair<>(
                        DateUtil.safeCreateFromMinValue(referenceDate.getYear(), referenceDate.getMonthValue(), 1),
                        referenceDate));
                ret.setPastValue(new Pair<>(
                        DateUtil.safeCreateFromMinValue(referenceDate.getYear(), referenceDate.getMonthValue(), 1),
                        referenceDate));

                ret.setSuccess(true);
                return ret;
            }

            if (!StringUtility.isNullOrEmpty(monthStr)) {
                swift = this.config.getSwiftYear(trimmedText);

                month = this.config.getMonthOfYear().get(monthStr.toLowerCase());

                if (swift >= -1) {
                    ret.setTimex(String.format("%04d-%02d", referenceDate.getYear() + swift, month));
                    year = year + swift;
                    futureYear = pastYear = year;
                } else {
                    ret.setTimex(String.format("XXXX-%02d", month));
                    if (month < referenceDate.getMonthValue()) {
                        futureYear++;
                    }

                    if (month >= referenceDate.getMonthValue()) {
                        pastYear--;
                    }
                }
            } else {
                swift = this.config.getSwiftDayOrMonth(trimmedText);

                if (this.config.isWeekOnly(trimmedText)) {
                    LocalDateTime thursday = DateUtil.thisDate(referenceDate, DayOfWeek.THURSDAY.getValue()).plusDays(Constants.WeekDayCount * swift);

                    ret.setTimex(isRef ? TimexUtility.generateWeekTimex() : TimexUtility.generateWeekTimex(thursday));

                    LocalDateTime beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.MONDAY.getValue()).plusDays(Constants.WeekDayCount * swift);

                    LocalDateTime endValue = DateUtil.thisDate(referenceDate, DayOfWeek.SUNDAY.getValue()).plusDays(Constants.WeekDayCount * swift);

                    LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);

                    if (earlyPrefix) {
                        endValue = DateUtil.thisDate(referenceDate, DayOfWeek.WEDNESDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
                        endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
                    } else if (midPrefix) {
                        beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.TUESDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
                        endValue = DateUtil.thisDate(referenceDate, DayOfWeek.FRIDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
                        endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
                    } else if (latePrefix) {
                        beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.THURSDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
                    }

                    if (earlierPrefix && swift == 0) {
                        if (endDate.isAfter(referenceDate)) {
                            endDate = referenceDate;
                        }
                    } else if (laterPrefix && swift == 0) {
                        if (beginDate.isBefore(referenceDate)) {
                            beginDate = referenceDate;
                        }
                    }

                    if (latePrefix && swift != 0) {
                        ret.setMod(Constants.LATE_MOD);
                    }

                    ret.setFutureValue(new Pair<>(beginDate, endDate));
                    ret.setPastValue(new Pair<>(beginDate, endDate));

                    ret.setSuccess(true);
                    return ret;
                }

                if (this.config.isWeekend(trimmedText)) {
                    LocalDateTime beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.SATURDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
                    LocalDateTime endValue = DateUtil.thisDate(referenceDate, DayOfWeek.SUNDAY.getValue()).plusDays(Constants.WeekDayCount * swift);

                    ret.setTimex(isRef ? TimexUtility.generateWeekendTimex() : TimexUtility.generateWeekendTimex(beginDate));

                    LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);

                    ret.setFutureValue(new Pair<>(beginDate, endDate));
                    ret.setPastValue(new Pair<>(beginDate, endDate));

                    ret.setSuccess(true);
                    return ret;
                }

                if (this.config.isMonthOnly(trimmedText)) {
                    LocalDateTime date = referenceDate.plusMonths(swift);
                    month = date.getMonthValue();
                    year = date.getYear();

                    ret.setTimex(isRef ? TimexUtility.generateMonthTimex() : TimexUtility.generateMonthTimex(date));

                    futureYear = pastYear = year;
                } else if (this.config.isYearOnly(trimmedText)) {
                    LocalDateTime date = referenceDate.plusYears(swift);
                    year = date.getYear();

                    if (!StringUtility.isNullOrEmpty(match.getMatch().get().getGroup("special").value)) {
                        String specialYearPrefixes = this.config.getSpecialYearPrefixesMap().get(match.getMatch().get().getGroup("special").value.toLowerCase());
                        swift = this.config.getSwiftYear(trimmedText);
                        year = swift < -1 ? Constants.InvalidYear : year;
                        ret.setTimex(TimexUtility.generateYearTimex(year, specialYearPrefixes));
                        ret.setSuccess(true);
                        return ret;
                    }

                    LocalDateTime beginDate = DateUtil.safeCreateFromMinValue(year, 1, 1);

                    LocalDateTime endValue = DateUtil.safeCreateFromMinValue(year, 12, 31);
                    LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);

                    if (earlyPrefix) {
                        endValue = DateUtil.safeCreateFromMinValue(year, 6, 30);
                        endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
                    } else if (midPrefix) {
                        beginDate = DateUtil.safeCreateFromMinValue(year, 4, 1);
                        endValue = DateUtil.safeCreateFromMinValue(year, 9, 30);
                        endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
                    } else if (latePrefix) {
                        beginDate = DateUtil.safeCreateFromMinValue(year, 7, 1);
                    }

                    if (earlierPrefix && swift == 0) {
                        if (endDate.isAfter(referenceDate)) {
                            endDate = referenceDate;
                        }
                    } else if (laterPrefix && swift == 0) {
                        if (beginDate.isBefore(referenceDate)) {
                            beginDate = referenceDate;
                        }
                    }

                    year = isRef ? Constants.InvalidYear : year;
                    ret.setTimex(TimexUtility.generateYearTimex(year));

                    ret.setFutureValue(new Pair<>(beginDate, endDate));
                    ret.setPastValue(new Pair<>(beginDate, endDate));

                    ret.setSuccess(true);
                    return ret;
                }
            }
        } else {
            return ret;
        }

        // only "month" will come to here
        LocalDateTime futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 1);
        LocalDateTime futureEnd = inclusiveEndPeriod ? futureStart.plusMonths(1).minusDays(1) : futureStart.plusMonths(1);


        LocalDateTime pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 1);
        LocalDateTime pastEnd = inclusiveEndPeriod ? pastStart.plusMonths(1).minusDays(1) : pastStart.plusMonths(1);

        if (earlyPrefix) {
            futureEnd = inclusiveEndPeriod ?
                    DateUtil.safeCreateFromMinValue(futureYear, month, 15) :
                    DateUtil.safeCreateFromMinValue(futureYear, month, 15).plusDays(1);
            pastEnd = inclusiveEndPeriod ?
                    DateUtil.safeCreateFromMinValue(pastYear, month, 15) :
                    DateUtil.safeCreateFromMinValue(pastYear, month, 15).plusDays(1);
        } else if (midPrefix) {
            futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 10);
            pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 10);
            futureEnd = inclusiveEndPeriod ?
                    DateUtil.safeCreateFromMinValue(futureYear, month, 20) :
                    DateUtil.safeCreateFromMinValue(futureYear, month, 20).plusDays(1);
            pastEnd = inclusiveEndPeriod ?
                    DateUtil.safeCreateFromMinValue(pastYear, month, 20) :
                    DateUtil.safeCreateFromMinValue(pastYear, month, 20).plusDays(1);
        } else if (latePrefix) {
            futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 16);
            pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 16);
        }

        if (earlierPrefix && futureEnd.isEqual(pastEnd)) {
            if (futureEnd.isAfter(referenceDate)) {
                futureEnd = pastEnd = referenceDate;
            }
        } else if (laterPrefix && futureStart.isEqual(pastStart)) {
            if (futureStart.isBefore(referenceDate)) {
                futureStart = pastStart = referenceDate;
            }
        }

        ret.setFutureValue(new Pair<>(futureStart, futureEnd));

        ret.setPastValue(new Pair<>(pastStart, pastEnd));

        ret.setSuccess(true);

        return ret;
    }