{"record":{"id":"e2c9616b596c4ec8","repo":"sansan0/TrendRadar","slug":"date-strftime-y-m-d-days-ago","errorCode":null,"errorMessage":"日期太久远: {date.strftime('%Y-%m-%d')} ({days_ago}天前)","messagePattern":"日期太久远: (.+?) \\((.+?)天前\\)","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"mcp_server/utils/date_parser.py","lineNumber":325,"sourceCode":"                f\"不能查询未来的日期: {date.strftime('%Y-%m-%d')}\",\n                suggestion=\"请使用今天或过去的日期\"\n            )\n\n    @staticmethod\n    def validate_date_not_too_old(date: datetime, max_days: int = 365) -> None:\n        \"\"\"\n        验证日期不太久远\n\n        Args:\n            date: 待验证的日期\n            max_days: 最大天数\n\n        Raises:\n            InvalidParameterError: 日期太久远\n        \"\"\"\n        days_ago = (datetime.now().date() - date.date()).days\n        if days_ago > max_days:\n            raise InvalidParameterError(\n                f\"日期太久远: {date.strftime('%Y-%m-%d')} ({days_ago}天前)\",\n                suggestion=f\"请查询{max_days}天内的数据\"\n            )\n\n    @staticmethod\n    def resolve_date_range_expression(expression: str) -> Dict:\n        \"\"\"\n        将自然语言日期表达式解析为标准日期范围\n\n        这是专门为 MCP 工具设计的方法，用于在服务器端解析日期表达式，\n        避免 AI 模型自己计算日期导致的不一致问题。\n\n        Args:\n            expression: 自然语言日期表达式，支持：\n                - 单日: \"今天\", \"昨天\", \"today\", \"yesterday\"\n                - 本周/上周: \"本周\", \"上周\", \"this week\", \"last week\"\n                - 本月/上月: \"本月\", \"上月\", \"this month\", \"last month\"\n                - 最近N天: \"最近7天\", \"最近30天\", \"last 7 days\", \"last 30 days\"","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/sansan0/TrendRadar/blob/8ee26026ba6c11dec41a95fb3895a7162876caa1/mcp_server/utils/date_parser.py#L307-L343","documentation":"Thrown by DateParser.validate_date_not_too_old when the parsed date is more than max_days (default 365) before today. Together with the not-future check it bounds queries to a rolling one-year window that matches the data retention period.","triggerScenarios":"Calling the validator (directly or via a tool that enforces the window) with a date more than 365 days in the past; long-horizon historical research queries; archived dates from previous years.","commonSituations":"Backfill scripts targeting older data; users asking for '去年今天' near the boundary; forgetting the default max_days is 365 when the tool only stores a year.","solutions":["Query dates within the last 365 days","If you control the call and retention allows, pass a larger max_days explicitly","Split older ranges out or accept they are outside the dataset's coverage"],"exampleFix":"# before\nDateParser.validate_date_not_too_old(datetime(2020, 1, 1))  # raises, default 365\n\n# after\nDateParser.validate_date_not_too_old(datetime(2020, 1, 1), max_days=3650)  # if retention allows\n# or query within the last year:\nDateParser.validate_date_not_too_old(datetime.now() - timedelta(days=200))","handlingStrategy":"validation","validationCode":"from datetime import datetime, timedelta\n\ndef within_retention(d: datetime, max_days: int = 365) -> bool:\n    return (datetime.now().date() - d.date()).days <= max_days","typeGuard":"def is_within_max_days(d, max_days=365) -> bool:\n    from datetime import datetime\n    return (datetime.now().date() - d.date()).days <= max_days","tryCatchPattern":"try:\n    DateParser.validate_date_not_too_old(d)\nexcept InvalidParameterError as e:\n    if \"太久远\" in str(e):\n        d = datetime.now() - timedelta(days=365)  # clamp to retention window\n    else:\n        raise","preventionTips":["Bound query windows to the one-year retention period by default","Pass max_days explicitly if your deployment retains more history","Clamp old dates to the window edge instead of dropping the whole query"],"tags":["date","validation","limits","retention"],"backgroundTag":null,"analyzedSha":"8ee26026ba6c11dec41a95fb3895a7162876caa1","analyzedAt":"2026-08-15T01:42:18.084Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}