Skip to content

Fix weekday modifiers after global calendar layout changes - #1039

Open
FanWu-ai wants to merge 1 commit into
python-pendulum:masterfrom
FanWu-ai:fix/calendar-weekday-layout-20261009
Open

FanWu-ai wants to merge 1 commit 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

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

This branch has not been deployed

No deployments
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.

1 participant