使用分隔符的日期验证作业实现技术咨询
Hey there! Building this date validator/formatter is totally doable with a structured approach. Let's walk through how to tackle it step by step, including a practical code example since it's great for this kind of text and date handling.
First, let's make sure we're aligned on what needs to be done:
- Accept flexible input formats: days as
dd,d, or0d; months asmm,m,0m, or case-insensitive 3-letter abbreviations (e.g.,Jan,jul,FEB) - Validate the date: flag invalid entries with a clear reason (like "年份超出范围" or "日期超出当月范围")
- Format valid dates to the exact
dd Mmm yyyystyle (e.g.,01 Apr 1882)
1. Set Up Month Mapping
We need two-way mappings to handle both numeric and text month inputs, and to format the output correctly:
- Map 3-letter month abbreviations (case-insensitive) to numeric values
- Map numeric months back to capitalized abbreviations for the final output
2. Parse & Validate Each Component
Break the input string into day, month, year, then validate each part:
- Year: Convert to integer and check if it falls within your required range (the example shows 3062 is invalid, so define
min_yearandmax_yearbased on your assignment specs) - Month: First try converting to an integer (to handle
03,3, etc.). If that fails, normalize the input to lowercase, take the first 3 characters, and look it up in our abbreviation map. If neither works, the month is invalid. - Day: Convert to integer, then check if it's valid for the given month and year (account for 30-day months, February's leap year rules)
3. Format or Return Error
If all checks pass, format the day to two digits, use the capitalized month abbreviation, and output the full date. If any check fails, return the input string with a clear "INVALID" message.
Here's a function that puts all this together:
def validate_and_format_date(input_str): # Map 3-letter month abbreviations (lowercase) to numeric values month_abbr_to_num = { "jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6, "jul": 7, "aug": 8, "sep": 9, "oct": 10, "nov": 11, "dec": 12 } # Reverse mapping for formatted output (numeric month → capitalized abbreviation) num_to_month_abbr = {v: k.title() for k, v in month_abbr_to_num.items()} # Adjust these based on your assignment's year range requirements MIN_YEAR = 1882 MAX_YEAR = 3061 try: # Split input into day, month, year (strip extra whitespace first) day_str, month_str, year_str = input_str.strip().split() # Validate year year = int(year_str) if not (MIN_YEAR <= year <= MAX_YEAR): return f"{input_str} - INVALID: 年份超出范围" # Validate month month = None # Try numeric month first (handles 03, 3, 012? Wait no—int("012") becomes 12, which is valid) try: month = int(month_str) if not 1 <= month <= 12: return f"{input_str} - INVALID: 月份无效" except ValueError: # Fall back to abbreviation matching normalized_abbr = month_str.lower()[:3] month = month_abbr_to_num.get(normalized_abbr) if month is None: return f"{input_str} - INVALID: 月份无效" # Validate day day = int(day_str) # Determine max days for the given month/year if month in [4, 6, 9, 11]: max_day = 30 elif month == 2: # Leap year check: divisible by 4, not by 100 unless also by 400 is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0) max_day = 29 if is_leap else 28 else: max_day = 31 if not 1 <= day <= max_day: return f"{input_str} - INVALID: 日期超出当月范围" # Format valid date to required style formatted_day = f"{day:02d}" formatted_month = num_to_month_abbr[month] return f"{formatted_day} {formatted_month} {year}" except ValueError: # Catch cases where input isn't split into 3 parts, or non-numeric day/year return f"{input_str} - INVALID: 输入格式不正确"
Let's run through some examples to make sure it works:
- Input:
03 JUL 3062→ Output:03 JUL 3062 - INVALID: 年份超出范围 - Input:
1 apr 1882→ Output:01 Apr 1882 - Input:
29 Feb 2023→ Output:29 Feb 2023 - INVALID: 日期超出当月范围 - Input:
05 09 2000→ Output:05 Sep 2000 - Input:
31 04 2024→ Output:31 04 2024 - INVALID: 日期超出当月范围
- Adjust
MIN_YEARandMAX_YEARto match your assignment's exact requirements - If your input might use other separators (like
/or.), add a step to replace them with spaces before splitting - The function handles extra whitespace around the input thanks to
strip()
内容的提问来源于stack exchange,提问作者user2930414

