def parse_implicit_date()

in Python/libraries/recognizers-date-time/recognizers_date_time/date_time/chinese/date_parser.py [0:0]


    def parse_implicit_date(self, source: str, reference: datetime) -> DateTimeResolutionResult:
        trimmed_source = source.strip()
        result = DateTimeResolutionResult()

        # handle "十二日" "明年这个月三日" "本月十一日"
        match = regex.match(self.special_date_regex, trimmed_source)
        if match:
            year_str = RegExpUtility.get_group(match, 'thisyear')
            month_str = RegExpUtility.get_group(match, 'thismonth')
            day_str = RegExpUtility.get_group(match, 'day')

            month = reference.month
            day = 0
            day = self.config.day_of_month[day_str]
            year = reference.year

            has_year = False
            has_month = False

            if month_str:
                has_month = True
                if regex.search(self.token_next_regex, month_str):
                    month += 1
                    if month == Constants.MAX_MONTH + 1:
                        month = Constants.MIN_MONTH
                        year += 1
                elif regex.search(self.token_last_regex, month_str):
                    month -= 1
                    if month == Constants.MIN_MONTH - 1:
                        month = Constants.MAX_MONTH
                        year -= 1

                if year_str:
                    has_year = True
                    if regex.search(self.token_next_regex, year_str):
                        year += 1
                    elif regex.search(self.token_last_regex, year_str):
                        year -= 1

            result.timex = DateTimeFormatUtil.luis_date(
                year if has_year else -1, month if has_month else -1, day)

            if day > self.get_month_max_day(year, month):
                future_month = month + 1
                past_month = month - 1
                future_year = year
                past_year = year

                if future_month == Constants.MAX_MONTH + 1:
                    future_month = Constants.MIN_MONTH
                    future_year = year + 1

                if past_month == Constants.MIN_MONTH - 1:
                    past_month = Constants.MAX_MONTH
                    past_year = year - 1

                is_future_valid = DateUtils.is_valid_date(
                    future_year, future_month, day)
                is_past_valid = DateUtils.is_valid_date(past_year, past_month, day)

                if is_future_valid and is_past_valid:
                    future_date = DateUtils.safe_create_from_min_value(future_year, future_month, day)
                    past_date = DateUtils.safe_create_from_min_value(past_year, past_month, day)
                elif is_future_valid and not is_past_valid:
                    future_date = past_date = DateUtils.safe_create_from_min_value(future_year, future_month, day)
                elif not is_future_valid and not is_past_valid:
                    future_date = past_date = DateUtils.safe_create_from_min_value(past_year, past_month, day)
                else:
                    future_date = past_date = DateUtils.safe_create_from_min_value(year, month, day)
            else:
                future_date = DateUtils.safe_create_from_min_value(year, month, day)
                past_date = DateUtils.safe_create_from_min_value(year, month, day)

                if not has_month:
                    if future_date < reference:
                        if self.is_valid_date(year, month + 1, day):
                            future_date += datedelta(months=1)
                    if past_date >= reference:
                        if self.is_valid_date(year, month - 1, day):
                            past_date += datedelta(months=-1)
                        elif DateUtils.is_Feb_29th(year, month - 1, day):
                            past_date += datedelta(months=-2)
                elif not has_year:
                    if future_date < reference:
                        if self.is_valid_date(year + 1, month, day):
                            future_date += datedelta(years=1)
                    if past_date >= reference:
                        if self.is_valid_date(year - 1, month, day):
                            past_date += datedelta(years=-1)

            result.future_value = future_date
            result.past_value = past_date
            result.success = True

            return result

        # handle "today", "the day before yesterday"
        match = regex.match(self.config.special_day_regex, trimmed_source)
        if match and match.start() == 0 and len(match.group()) == len(trimmed_source):
            swift = self.config.get_swift_day(match.group())
            value = reference + timedelta(days=swift)

            result.timex = DateTimeFormatUtil.luis_date_from_datetime(value)
            result.future_value = result.past_value = DateUtils.safe_create_from_min_value(value.year, value.month,
                                                                                           value.day)
            result.success = True
            return result

        # handle "this Friday"
        match = regex.match(self.config.this_regex, trimmed_source)
        if match and match.start() == 0 and len(match.group()) == len(trimmed_source):
            weekday_str = RegExpUtility.get_group(match, 'weekday')
            value = DateUtils.this(
                reference, self.config.day_of_week.get(weekday_str))

            result.timex = DateTimeFormatUtil.luis_date_from_datetime(value)
            result.future_value = value
            result.past_value = value
            result.success = True
            return result

        # handle "next Sunday"
        match = regex.match(self.config.next_regex, trimmed_source)
        if match and match.start() == 0 and len(match.group()) == len(trimmed_source):
            weekday_str = RegExpUtility.get_group(match, 'weekday')
            value = DateUtils.next(
                reference, self.config.day_of_week.get(weekday_str))

            result.timex = DateTimeFormatUtil.luis_date_from_datetime(value)
            result.future_value = value
            result.past_value = value
            result.success = True
            return result

        # handle "last Friday", "last mon"
        match = regex.match(self.config.last_regex, trimmed_source)
        if match and match.start() == 0 and len(match.group()) == len(trimmed_source):
            weekday_str = RegExpUtility.get_group(match, 'weekday')
            value = DateUtils.last(
                reference, self.config.day_of_week.get(weekday_str))

            result.timex = DateTimeFormatUtil.luis_date_from_datetime(value)
            result.future_value = value
            result.past_value = value
            result.success = True
            return result

        # handle "Friday"
        match = regex.match(self.config.week_day_regex, trimmed_source)
        if match and match.start() == 0 and len(match.group()) == len(trimmed_source):
            weekday_str = RegExpUtility.get_group(match, 'weekday')
            weekday = self.config.day_of_week.get(weekday_str)
            value = DateUtils.this(reference, weekday)

            if weekday == 0:
                weekday = 7

            if weekday < reference.isoweekday():
                value = DateUtils.next(reference, weekday)

            result.timex = 'XXXX-WXX-' + str(weekday)
            future_date = value
            past_date = value

            if future_date < reference:
                future_date += timedelta(weeks=1)

            if past_date >= reference:
                past_date -= timedelta(weeks=1)

            result.future_value = future_date
            result.past_value = past_date
            result.success = True
            return result

        return result