Skip to content

Fix weekday modifiers after global calendar layout changes - #1039

Merged
ashb merged 2 commits into
python-pendulum:masterfrom
FanWu-ai:fix/calendar-weekday-layout-20261009
Oct 10, 2026
Merged

ashb merged 2 commits into
python-pendulum:masterfrom
FanWu-ai:fix/calendar-weekday-layout-20261009

Conversation

@FanWu-ai

@FanWu-ai FanWu-ai commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Date and DateTime weekday modifiers use Monday-based weekday constants to index calendar.monthcalendar(). That function follows the standard library's process-wide first-weekday setting, so changing the calendar display layout also changes which dates Pendulum selects:

import calendar
import pendulum

calendar.setfirstweekday(calendar.SUNDAY)
pendulum.date(2026, 10, 15).first_of('month', pendulum.MONDAY)
# Before: Date(2026, 10, 4), a Sunday
# After:  Date(2026, 10, 5), a Monday

Use a separate Monday-based Calendar instance for the four month-calendar lookups. This fixes first_of, last_of, and the first occurrence in nth_of for month, quarter, and year units. The caller's global calendar setting is never changed. No API or dependency changes.

Tests

  • Fourteen parametrized regression groups cover both classes and all seven global first-weekday settings. They check all requested weekdays, leap/non-leap February, month/quarter/year units, first/last/first-and-second occurrence, omitted weekday arguments, preserved timezones and midnight normalization, and state preservation after invalid arguments.
  • Original source: 12 groups fail and the two Monday-layout controls pass. Fixed source: all 14 pass.
  • Independent calendar oracle over every month in 2024 and 2025: 28,224 cases pass. The original source gives 18,144 incorrect dates for the same cases.
  • An additional 1,000 concurrent queries return the correct dates without changing the caller's calendar setting.

Validation

Linux, CPython 3.12.14:

  • Original full pure-Python and native suites: 1,854 passed, 3 existing skips each.
  • Final full pure-Python and rebuilt native suites: 1,868 passed, 3 existing skips each.
  • Repeated both complete suites against the built baseline/final release wheels in a clean runtime environment without typing_extensions: same passing results.
  • Mypy: all 228 source files pass.
  • Every configured prek hook passes, including Ruff, Rust formatting and Clippy.
  • Strict MkDocs, release wheel/sdist builds, strict Twine checks, and git diff --check pass. Built Python source files were verified against the checkout.

The existing skips cover Windows-specific local-timezone behavior and two upstream timezone-rule tests. The documentation build retains six pre-existing info-level link diagnostics; source-distribution generation retains upstream Cargo metadata diagnostics. Other interpreters, operating systems, and hosted CI are not claimed as tested locally.

  • Added tests for changed code
  • Updated documentation

AI assistance was used to prepare the implementation and regression tests.

AI assistance was used to prepare the implementation and regression tests.
@FanWu-ai
FanWu-ai marked this pull request as ready for review October 8, 2026 22:26
@ashb

ashb commented Oct 9, 2026

Copy link
Copy Markdown
Member

"standard library's process-wide first-weekday setting". TIL that that was even a thing.

Personal view (not saying we won't fix this, just) Monday is the start of the week. Sunday is the end, it's a "Weekend" day. It's right there in the name 😉

@codspeed

codspeed Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 1 benchmark spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

ℹ️ 1 benchmark has no flame graph

The flamegraph could not be generated because we failed to resolve the symbols in the profiling trace. This happens when we fail to harvest information about language frames.

✅ 1 untouched benchmark


Comparing FanWu-ai:fix/calendar-weekday-layout-20261009 (b927a70) with master (b97a3f0)

Open in CodSpeed

Comment thread src/pendulum/date.py Outdated
@ashb
ashb merged commit 24ff0e5 into python-pendulum:master Oct 10, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants