protected parseSpecificTimeOfDay()

in JavaScript/packages/recognizers-date-time/src/dateTime/baseDateTimePeriod.ts [606:760]


    protected parseSpecificTimeOfDay(source: string, referenceDate: Date): DateTimeResolutionResult {
        let result = new DateTimeResolutionResult();
        let timeText = source;
        let hasEarly = false;
        let hasLate = false;

        let match = RegExpUtility.getMatches(this.config.periodTimeOfDayWithDateRegex, source).pop();
        if (match) {
            timeText = match.groups('timeOfDay').value;
            if (!StringUtility.isNullOrEmpty(match.groups('early').value)) {
                hasEarly = true;
                result.comment = 'early';
                result.mod = Constants.EARLY_MOD;
            }
            else if (!StringUtility.isNullOrEmpty(match.groups('late').value)) {
                hasLate = true;
                result.comment = 'late';
                result.mod = Constants.LATE_MOD;
            }
        }

        let matched = this.config.getMatchedTimeRange(timeText);
        if (!matched || !matched.success) {
            return result;
        }

        if (hasEarly) {
            matched.endHour = matched.beginHour + 2;
            if (matched.endMin === 59) {
                matched.endMin = 0;
            }
        }
        else if (hasLate) {
            matched.beginHour += 2;
        }

        match = RegExpUtility.getMatches(this.config.specificTimeOfDayRegex, source).pop();
        if (match && match.index === 0 && match.length === source.length) {
            let swift = this.config.getSwiftPrefix(source);
            let date = DateUtils.addDays(referenceDate, swift);
            result.timex = DateTimeFormatUtil.formatDate(date) + matched.timeStr;
            result.futureValue = [
                DateUtils.safeCreateFromMinValue(date.getFullYear(), date.getMonth(), date.getDate(), matched.beginHour, 0, 0),
                DateUtils.safeCreateFromMinValue(date.getFullYear(), date.getMonth(), date.getDate(), matched.endHour, matched.endMin, matched.endMin),
            ];
            result.pastValue = [
                DateUtils.safeCreateFromMinValue(date.getFullYear(), date.getMonth(), date.getDate(), matched.beginHour, 0, 0),
                DateUtils.safeCreateFromMinValue(date.getFullYear(), date.getMonth(), date.getDate(), matched.endHour, matched.endMin, matched.endMin),
            ];
            result.success = true;
            return result;
        }

        match = RegExpUtility.getMatches(this.config.periodTimeOfDayWithDateRegex, source).pop();
        if (!match) {
            return result;
        }

        let beforeStr = source.substr(0, match.index).trim();
        let afterStr = source.substr(match.index + match.length).trim();
        let ers = this.config.dateExtractor.extract(beforeStr, referenceDate);

        // eliminate time period, if any
        let timePeriodErs = this.config.timePeriodExtractor.extract(beforeStr);
        if (timePeriodErs.length > 0) {
            beforeStr = beforeStr.slice(timePeriodErs[0].start || 0, timePeriodErs[0].start + timePeriodErs[0].length || 0).trim();
        }
        else {
            timePeriodErs = this.config.timePeriodExtractor.extract(afterStr);
            if (timePeriodErs.length > 0) {
                afterStr = afterStr.slice(timePeriodErs[0].start || 0, timePeriodErs[0].start + timePeriodErs[0].length || 0).trim();
            }
        }

        if (ers.length === 0 || ers[0].length !== beforeStr.length) {
            let valid = false;
            if (ers.length > 0 && ers[0].start === 0) {
                let midStr = beforeStr.substr(ers[0].start + ers[0].length || 0);
                if (StringUtility.isNullOrWhitespace(midStr.replace(',', ' '))) {
                    valid = true;
                }
            }

            if (!valid) {
                ers = this.config.dateExtractor.extract(afterStr);
                if (ers.length === 0 || ers[0].length !== afterStr.length) {
                    if (ers.length > 0 && ers[0].start + ers[0].length === afterStr.length) {
                        let midStr = afterStr.substr(0, ers[0].start || 0);
                        if (StringUtility.isNullOrWhitespace(midStr.replace(',', ' '))) {
                            valid = true;
                        }
                    }
                }
                else {
                    valid = true;
                }

                if (!valid) {
                    return result;
                }
            }
        }

        let hasSpecificTimePeriod = false;
        if (timePeriodErs.length > 0) {
            let TimePr = this.config.timePeriodParser.parse(timePeriodErs[0], referenceDate);
            if (TimePr != null) {
                let periodFuture = TimePr.value.futureValue;
                let periodPast = TimePr.value.pastValue;

                if (periodFuture === periodPast) {
                    matched.beginHour = periodFuture.item1.getHours();
                    matched.endHour = periodFuture.item2.getHours();
                }
                else {
                    if (periodFuture.item1.Hour >= matched.beginHour || periodFuture.item2.Hour <= matched.endHour) {
                        matched.beginHour = periodFuture.item1.getHours();
                        matched.endHour = periodFuture.item2.getHours();
                    }
                    else {
                        matched.beginHour = periodPast.item1.getHours();
                        matched.endHour = periodPast.item2.getHours();
                    }
                }
                hasSpecificTimePeriod = true;
            }
        }

        let pr = this.config.dateParser.parse(ers[0], referenceDate);
        if (!pr) {
            return result;
        }

        let futureDate: Date = pr.value.futureValue;
        let pastDate: Date = pr.value.pastValue;


        if (!hasSpecificTimePeriod) {
            result.timex = pr.timexStr + matched.timeStr;
        }
        else {
            result.timex = `(${pr.timexStr}T${matched.beginHour},${pr.timexStr}T${matched.endHour},PT${matched.endHour - matched.beginHour}H)`;
        }

        result.futureValue = [
            DateUtils.safeCreateFromMinValue(futureDate.getFullYear(), futureDate.getMonth(), futureDate.getDate(), matched.beginHour, 0, 0),
            DateUtils.safeCreateFromMinValue(futureDate.getFullYear(), futureDate.getMonth(), futureDate.getDate(), matched.endHour, matched.endMin, matched.endMin),
        ];
        result.pastValue = [
            DateUtils.safeCreateFromMinValue(pastDate.getFullYear(), pastDate.getMonth(), pastDate.getDate(), matched.beginHour, 0, 0),
            DateUtils.safeCreateFromMinValue(pastDate.getFullYear(), pastDate.getMonth(), pastDate.getDate(), matched.endHour, matched.endMin, matched.endMin),
        ];
        result.success = true;
        return result;
    }