如何在Python中将自然语言日期转换为标准时间段?求可用库或API
Absolutely, there are reliable Python libraries that can handle converting natural language date references like your examples into the standardized date range format you need. Let’s break down the best options with practical code examples:
1. dateparser – Intuitive Date Parsing
dateparser is a great choice for its flexibility with different date formats and natural language inputs. It can easily parse month-year strings and handle range descriptions with a bit of string processing.
First, install it:
pip install dateparser
Here’s a function that handles both your example cases:
import dateparser from datetime import timedelta def nl_to_date_range(nl_input): # Handle single month-year (e.g., "June 2016" or "06/2016") if not any(phrase in nl_input.lower() for phrase in ["to", "between", "and"]): # Parse the date, forcing the first day of the month parsed_date = dateparser.parse(nl_input, settings={"PREFER_DAY_OF_MONTH": "first"}) # Calculate the last day of the same month next_month = parsed_date.replace(day=28) + timedelta(days=4) last_day = next_month - timedelta(days=next_month.day) # Format as required return f"{parsed_date.strftime('%m/%d/%Y')}-{last_day.strftime('%m/%d/%Y')}" # Handle date ranges (e.g., "June 2016 to Dec 2016" or "between June 2016 and Dec 2016") else: # Clean up the input to extract start and end dates cleaned_input = nl_input.lower().replace("between ", "").replace(" and ", " to ") start_str, end_str = [part.strip() for part in cleaned_input.split("to")] # Parse start date (first day of month) and end date (we'll get last day) start_date = dateparser.parse(start_str, settings={"PREFER_DAY_OF_MONTH": "first"}) end_date = dateparser.parse(end_str, settings={"PREFER_DAY_OF_MONTH": "first"}) # Calculate last day of the end month next_month = end_date.replace(day=28) + timedelta(days=4) last_day_end = next_month - timedelta(days=next_month.day) return f"{start_date.strftime('%m/%d/%Y')}-{last_day_end.strftime('%m/%d/%Y')}" # Test your examples print(nl_to_date_range("June 2016")) # Output: 06/01/2016-06/30/2016 print(nl_to_date_range("06/2016")) # Output: 06/01/2016-06/30/2016 print(nl_to_date_range("June 2016 to Dec 2016")) # Output: 06/01/2016-12/31/2016 print(nl_to_date_range("between June 2016 and Dec 2016")) # Output: 06/01/2016-12/31/2016
2. parsedatetime – Robust Natural Language Support
If you need to handle more complex natural language phrases beyond your examples, parsedatetime is a powerful option that understands context better.
Install it first:
pip install parsedatetime
Here’s an adapted function for your use case:
import parsedatetime as pdt from datetime import datetime, timedelta cal = pdt.Calendar() def parse_date_range(nl_input): # Single month-year case if not any(phrase in nl_input.lower() for phrase in ["to", "between", "and"]): parsed_result, status = cal.parse(nl_input) if status == 1: # Successful parse parsed_date = datetime(*parsed_result[:6]) first_day = parsed_date.replace(day=1) # Get last day of the month next_month = first_day.replace(day=28) + timedelta(days=4) last_day = next_month - timedelta(days=next_month.day) return f"{first_day.strftime('%m/%d/%Y')}-{last_day.strftime('%m/%d/%Y')}" return "Failed to parse date" # Range case else: # Normalize input to use "to" as the separator cleaned_input = nl_input.lower().replace("between ", "").replace(" and ", " to ") start_str, end_str = [part.strip() for part in cleaned_input.split("to")] start_result, start_status = cal.parse(start_str) end_result, end_status = cal.parse(end_str) if start_status == 1 and end_status == 1: start_date = datetime(*start_result[:6]).replace(day=1) end_date = datetime(*end_result[:6]) # Calculate last day of end month next_month = end_date.replace(day=28) + timedelta(days=4) last_day_end = next_month - timedelta(days=next_month.day) return f"{start_date.strftime('%m/%d/%Y')}-{last_day_end.strftime('%m/%d/%Y')}" return "Failed to parse date range" # Test print(parse_date_range("Dec 2016")) # Output: 12/01/2016-12/31/2016 print(parse_date_range("06/2016 to 12/2016")) # Output: 06/01/2016-12/31/2016
Both libraries work well for your specific cases. dateparser is often more straightforward for simple inputs, while parsedatetime shines with more varied natural language.
内容的提问来源于stack exchange,提问作者Zhenshan Jin

