protected parseImplicitDate()

in JavaScript/packages/recognizers-date-time/src/dateTime/baseDate.ts [392:591]


    protected parseImplicitDate(source: string, referenceDate: Date): DateTimeResolutionResult {
        let trimmedSource = source.trim();
        let result = new DateTimeResolutionResult();
        // handle "on 12"
        let match = RegExpUtility.getMatches(this.config.onRegex, this.config.dateTokenPrefix + trimmedSource).pop();
        if (match && match.index === this.config.dateTokenPrefix.length && match.length === trimmedSource.length) {
            let day = 0;
            let month = referenceDate.getMonth();
            let year = referenceDate.getFullYear();
            let dayStr = match.groups('day').value;
            day = this.config.dayOfMonth.get(dayStr);

            result.timex = DateTimeFormatUtil.luisDate(-1, -1, day);

            let tryStr = DateTimeFormatUtil.luisDate(year, month, day);
            let tryDate = Date.parse(tryStr);
            let futureDate: Date;
            let pastDate: Date;

            if (tryDate && !isNaN(tryDate)) {
                futureDate = DateUtils.safeCreateFromMinValue(year, month, day);
                pastDate = DateUtils.safeCreateFromMinValue(year, month, day);
                if (futureDate < referenceDate) {
                    futureDate.setMonth(futureDate.getMonth() + 1);
                }

                if (pastDate >= referenceDate) {
                    pastDate.setMonth(pastDate.getMonth() - 1);
                }
            }
            else {
                futureDate = DateUtils.safeCreateFromMinValue(year, month + 1, day);
                pastDate = DateUtils.safeCreateFromMinValue(year, month - 1, day);
            }

            result.futureValue = futureDate;
            result.pastValue = pastDate;
            result.success = true;
            return result;
        }

        // handle "today", "the day before yesterday"
        match = RegExpUtility.getMatches(this.config.specialDayRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let swift = this.config.getSwiftDay(match.value);
            let today = DateUtils.safeCreateFromMinValue(referenceDate.getFullYear(), referenceDate.getMonth(), referenceDate.getDate());
            let value = DateUtils.addDays(today, swift);
            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "two days from tomorrow"
        match = RegExpUtility.getMatches(this.config.specialDayWithNumRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let swift = this.config.getSwiftDay(match.groups('day').value);
            let numErs = this.config.integerExtractor.extract(trimmedSource);
            let numOfDays = Number.parseInt(this.config.numberParser.parse(numErs[0]).value);

            let value = DateUtils.addDays(referenceDate, swift + numOfDays);
            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "two sundays from now"
        match = RegExpUtility.getMatches(this.config.relativeWeekDayRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let numErs = this.config.integerExtractor.extract(trimmedSource);
            let num = Number.parseInt(this.config.numberParser.parse(numErs[0]).value);
            let weekdayStr = match.groups('weekday').value.toLowerCase();
            let value = referenceDate;

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

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

            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "next Sunday"
        match = RegExpUtility.getMatches(this.config.nextRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let weekdayStr = match.groups('weekday').value;
            let value = DateUtils.next(referenceDate, this.config.dayOfWeek.get(weekdayStr));

            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "this Friday"
        match = RegExpUtility.getMatches(this.config.thisRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let weekdayStr = match.groups('weekday').value;
            let value = DateUtils.this(referenceDate, this.config.dayOfWeek.get(weekdayStr));

            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "last Friday", "last mon"
        match = RegExpUtility.getMatches(this.config.lastRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let weekdayStr = match.groups('weekday').value;
            let value = DateUtils.last(referenceDate, this.config.dayOfWeek.get(weekdayStr));

            result.timex = DateTimeFormatUtil.luisDateFromDate(value);
            result.futureValue = value;
            result.pastValue = value;
            result.success = true;
            return result;
        }

        // handle "Friday"
        match = RegExpUtility.getMatches(this.config.weekDayRegex, trimmedSource).pop();
        if (match && match.index === 0 && match.length === trimmedSource.length) {
            let weekdayStr = match.groups('weekday').value;
            let weekday = this.config.dayOfWeek.get(weekdayStr);
            let value = DateUtils.this(referenceDate, this.config.dayOfWeek.get(weekdayStr));

            if (weekday === 0) {
                weekday = 7;
            }
            if (weekday < referenceDate.getDay()) {
                value = DateUtils.next(referenceDate, weekday);
            }
            result.timex = 'XXXX-WXX-' + weekday;
            let futureDate = new Date(value);
            let pastDate = new Date(value);
            if (futureDate < referenceDate) {
                futureDate.setDate(value.getDate() + 7);
            }
            if (pastDate >= referenceDate) {
                pastDate.setDate(value.getDate() - 7);
            }

            result.futureValue = futureDate;
            result.pastValue = pastDate;
            result.success = true;
            return result;
        }

        // handle "for the 27th."
        match = RegExpUtility.getMatches(this.config.forTheRegex, trimmedSource).pop();
        if (match) {
            let dayStr = match.groups('DayOfMonth').value;
            let er = ExtractResult.getFromText(dayStr);
            let day = Number.parseInt(this.config.numberParser.parse(er).value);

            let month = referenceDate.getMonth();
            let year = referenceDate.getFullYear();

            result.timex = DateTimeFormatUtil.luisDate(-1, -1, day);
            let date = new Date(year, month, day);
            result.futureValue = date;
            result.pastValue = date;
            result.success = true;

            return result;
        }

        // handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
        match = RegExpUtility.getMatches(this.config.weekDayAndDayOfMonthRegex, trimmedSource).pop();
        if (match) {
            let dayStr = match.groups('DayOfMonth').value;
            let er = ExtractResult.getFromText(dayStr);
            let day = Number.parseInt(this.config.numberParser.parse(er).value);
            let month = referenceDate.getMonth();
            let year = referenceDate.getFullYear();

            // the validity of the phrase is guaranteed in the Date Extractor
            result.timex = DateTimeFormatUtil.luisDate(year, month, day);
            result.futureValue = new Date(year, month, day);
            result.pastValue = new Date(year, month, day);
            result.success = true;

            return result;
        }

        return result;
    }