27 lines
972 B
Python
27 lines
972 B
Python
|
|
"""月份参数校验(YYYY-MM)——叶子模块。
|
|||
|
|
|
|||
|
|
报表、月结与调整单共用同一套校验:只校验长度会放过 `2026-13` 这类
|
|||
|
|
非法月份,一路传到 `calendar.monthrange` 才抛 ValueError,最终被全局
|
|||
|
|
处理器当成服务端异常(500)。月份范围必须在入口处拦住,才能返回 400。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import re
|
|||
|
|
|
|||
|
|
_MONTH_RE = re.compile(r"^\d{4}-(0[1-9]|1[0-2])$")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def validate_month(value: str) -> str:
|
|||
|
|
"""校验 YYYY-MM 且月份 01-12;非法抛 ValueError(Pydantic 友好)。
|
|||
|
|
|
|||
|
|
年份 0000 也拒绝:`date(0, ...)` 同样会抛 ValueError,且业务上不存在。
|
|||
|
|
"""
|
|||
|
|
if not _MONTH_RE.match(value) or int(value[:4]) == 0:
|
|||
|
|
raise ValueError("月份格式须为 YYYY-MM(01-12)")
|
|||
|
|
return value
|
|||
|
|
|
|||
|
|
|
|||
|
|
def parse_month(value: str) -> tuple[int, int]:
|
|||
|
|
"""校验并返回 (year, month),供服务层计算月末等使用。"""
|
|||
|
|
validate_month(value)
|
|||
|
|
return int(value[:4]), int(value[5:7])
|