周号超出任何算法(W54 以上)的认不出、算起止超出日期范围的当这一周没有(复核 R3 补):认不出算法时原来按周号排先后,「2026-W99」也会当一周收下,现在周号大于 53 的不当周号写法,原因里照实举它;按算法算起止时日子超出日期能表示的范围(公元 9999 年末)交回没有这一周,不抛异常

This commit is contained in:
ThearchyHelios
2026-10-21 16:56:48 +08:00
parent f5e6e77ea9
commit 2efea2b753
2 changed files with 18 additions and 10 deletions
+11 -10
View File
@@ -126,7 +126,7 @@ def _shape(value: Any) -> str | None:
text = value.strip()
if (m := _MONTH.match(text)) and 1 <= int(m.group(2)) <= 12 and 1900 <= int(m.group(1)) <= 2200:
return "month"
if _WEEK.match(text):
if (m := _WEEK.match(text)) and int(m.group(2)) <= 53:
return "week"
if _QUARTER.match(text):
return "quarter"
@@ -161,17 +161,18 @@ def _first_weekday(start: date, weekday: int) -> date:
def week_span(scheme: str, year: int, week: int) -> tuple[date, date] | None:
"""按周号算法,year 年第 week 周覆盖的第一天和最后一天(含)。这种算法里没有这一周(ISO 只有 52 周的年份写了第 53 周、
1 月 1 日就是周一的年份写了第 0 周……)为 None。"""
if scheme == "iso":
try:
start = date.fromisocalendar(year, week, 1)
except ValueError:
return None
return start, start + timedelta(days=6)
1 月 1 日就是周一的年份写了第 0 周……)、日子超出日期能表示的范围的为 None。"""
try:
jan1, dec31 = date(year, 1, 1), date(year, 12, 31)
except ValueError:
return _week_span(scheme, year, week)
except (OverflowError, ValueError):
return None
def _week_span(scheme: str, year: int, week: int) -> tuple[date, date] | None:
if scheme == "iso":
start = date.fromisocalendar(year, week, 1)
return start, start + timedelta(days=6)
jan1, dec31 = date(year, 1, 1), date(year, 12, 31)
if scheme == "jan1":
if not 1 <= week <= 53:
return None
+7
View File
@@ -140,3 +140,10 @@ def test_a_plain_date_column_is_a_day_even_when_two_values_are_a_week_apart():
assert pd.parse_compared(["2026-10-13", "2026-10-20"], plain, "day", "sqlite")[1] == "day"
assert pd.parse_compared(["2026-10-12", "2026-10-19"], starts, "week", "sqlite")[1] == "week"
assert pd.parse_compared(["2026-09-01", "2026-10-01"], plain, "day", "sqlite")[1] == "month"
def test_week_numbers_out_of_any_algorithm_are_unreadable():
assert pd.parse(["2026-W41", "2026-W99"]) is None
assert pd.unreadable(["2026-W41", "2026-W99"]) == ("shape", ["2026-W99"])
assert pd.week_span("sunday_year", 9999, 53) is None and pd.week_span("iso", 0, 1) is None