protected parseImplicitDate()

in JavaScript/packages/recognizers-date-time/src/dateTime/chinese/dateConfiguration.ts [301:500]


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

            let hasYear = !StringUtility.isNullOrEmpty(yearStr);
            let hasMonth = !StringUtility.isNullOrEmpty(monthStr);

            if (hasMonth) {
                if (RegExpUtility.isMatch(this.tokenNextRegex, monthStr)) {
                    month++;
                    if (month === Constants.MaxMonth + 1) {
                        month = Constants.MinMonth;
                        year++;
                    }
                }
                else if (RegExpUtility.isMatch(this.tokenLastRegex, monthStr)) {
                    month--;
                    if (month === Constants.MinMonth - 1) {
                        month = Constants.MaxMonth;
                        year--;
                    }
                }
                if (hasYear) {
                    if (RegExpUtility.isMatch(this.tokenNextRegex, yearStr)) {
                        year++;
                    }
                    else if (RegExpUtility.isMatch(this.tokenLastRegex, yearStr)) {
                        year--;
                    }
                }
            }

            result.timex = DateTimeFormatUtil.luisDate(hasYear ? year : -1, hasMonth ? month : -1, day);
            let futureDate: Date;
            let pastDate: Date;

            if (day > this.getMonthMaxDay(year, month)) {
                let futureMonth = month + 1;
                let pastMonth = month - 1;
                let futureYear = year;
                let pastYear = year;

                if (futureMonth === Constants.MaxMonth + 1) {
                    futureMonth = Constants.MinMonth;
                    futureYear = year++;
                }
                if (pastMonth === Constants.MinMonth - 1) {
                    pastMonth = Constants.MaxMonth;
                    pastYear = year--;
                }

                let isFutureValid = DateUtils.isValidDate(futureYear, futureMonth, day);
                let isPastValid = DateUtils.isValidDate(pastYear, pastMonth, day);

                if (isFutureValid && isPastValid) {
                    futureDate = DateUtils.safeCreateFromMinValue(futureYear, futureMonth, day);
                    pastDate = DateUtils.safeCreateFromMinValue(pastYear, pastMonth, day);
                }
                else if (isFutureValid && !isPastValid) {
                    futureDate = pastDate = DateUtils.safeCreateFromMinValue(futureYear, futureMonth, day);
                }
                else if (!isFutureValid && !isPastValid) {
                    futureDate = pastDate = DateUtils.safeCreateFromMinValue(pastYear, pastMonth, day);
                }
                else {
                    futureDate = pastDate = DateUtils.safeCreateFromMinValue(year, month, day);
                }
            }
            else {
                futureDate = DateUtils.safeCreateFromMinValue(year, month, day);
                pastDate = DateUtils.safeCreateFromMinValue(year, month, day);

                if (!hasMonth) {
                    if (futureDate < referenceDate) {
                        if (this.isValidDate(year, month + 1, day)) {
                            futureDate = DateUtils.addMonths(futureDate, 1);
                        }
                    }
                    if (pastDate >= referenceDate) {
                        if (this.isValidDate(year, month - 1, day)) {
                            pastDate = DateUtils.addMonths(pastDate, -1);
                        }
                        else if (DateUtils.isFeb29th(year, month - 1, day)) {
                            pastDate = DateUtils.addMonths(pastDate, -2);
                        }
                    }
                }
                else if (hasMonth && !hasYear) {
                    if (futureDate < referenceDate) {
                        if (DateUtils.isValidDate(year + 1, month, day)) {
                            futureDate = DateUtils.addYears(futureDate, 1);
                        }
                    }
                    if (pastDate >= referenceDate) {
                        if (DateUtils.isValidDate(year - 1, month, day)) {
                            pastDate = DateUtils.addYears(pastDate, -1);
                        }
                    }
                }
            }

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

        // handle cases like "昨日", "明日", "大后天"
        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 value = DateUtils.addDays(referenceDate, swift);

            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 "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 "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, weekday);

            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 = DateUtils.addDays(futureDate, 7);
            }
            if (pastDate >= referenceDate) {
                pastDate = DateUtils.addDays(pastDate, -7);
            }

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

        return result;
    }