Skip to content

Update Chinese calendar: improve Qingming Festival date calculation#3119

Merged
arkid15r merged 4 commits intovacanza:devfrom
KJhellico:upd-calendar-qingming
Dec 11, 2025
Merged

Update Chinese calendar: improve Qingming Festival date calculation#3119
arkid15r merged 4 commits intovacanza:devfrom
KJhellico:upd-calendar-qingming

Conversation

@KJhellico
Copy link
Copy Markdown
Collaborator

Proposed change

Update Chinese calendar:

  • improve Qingming Festival date calculation in 1901-2099
  • extend Winter Solstice calculations range to 1901-2099 also

This holiday isn't observed in Vietnam, but Vietnamese calendar support has been added for unification purposes.

Type of change

  • New country/market holidays support (thank you!)
  • Supported country/market holidays update (calendar discrepancy fix, localization)
  • Existing code/documentation/test/process quality improvement (best practice, cleanup, refactoring, optimization)
  • Dependency update (version deprecation/pin/upgrade)
  • Bugfix (non-breaking change which fixes an issue)
  • Breaking change (a code change causing existing functionality to break)
  • New feature (new holidays functionality in general)

Checklist

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 9, 2025

Summary by CodeRabbit

  • New Features

    • Added Qingming (Tomb‑Sweeping/Cheongmyeong) date support across Chinese, Korean, and Vietnamese lunar calendars.
  • Bug Fixes

    • Refined Winter Solstice date selection logic for improved date accuracy across lunar calendars.
  • Snapshot Updates

    • Adjusted holiday dates and observed/combined labels for China, Hong Kong, North Korea, Macau, and Taiwan (multiple years).
  • Tests

    • Added extensive tests covering Qingming and Winter Solstice date calculations and estimation flags.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds calendar-aware Qingming date computation (returns date + reliability flag), extends winter-solstice threshold mappings and reliability bounds, updates Chinese-holiday group helpers to call the lunisolar calendar methods, updates many country snapshot dates for Tomb‑Sweeping/Cheongmyeong and related observances, and expands tests for Qingming and winter solstice across calendars.

Changes

Cohort / File(s) Summary
Calendar logic
holidays/calendars/chinese.py
Adds qingming_date(year, calendar=None) returning (date, bool), introduces QINGMING_THRESHOLDS, extends WINTER_SOLSTICE_THRESHOLDS to include dec_23 variants, and changes the reliability boundary to 1901–2099 for solstice/qingming semantics.
Holiday group refactor
holidays/groups/chinese.py
Replaces inline Qingming/Dongzhi calculations with Chinese lunisolar helper calls; _add_qingming_festival now uses _add_chinese_calendar_holiday and returns `date
Snapshots — China / Korea / Macau
snapshots/countries/CN_COMMON.json, snapshots/countries/KP_COMMON.json, snapshots/countries/MO_COMMON.json, snapshots/countries/MO_I.json, snapshots/countries/MO_M.json
Normalizes and shifts Tomb‑Sweeping / Cheongmyeong dates (notably 2042/2046/2050), merges some Good Friday + Tomb‑Sweeping entries, and adjusts compensatory/rest-day entries.
Snapshots — Hong Kong / Taiwan
snapshots/countries/HK_COMMON.json, snapshots/countries/TW_COMMON.json
Shifts Tomb‑Sweeping occurrences (04‑04 → 04‑05) and adds observed variants or consolidated labels across many years.
Snapshots — Macau (I/M variants)
snapshots/countries/MO_I.json, snapshots/countries/MO_M.json
Merges and relabels combined holiday entries (Good Friday; Tomb‑Sweeping Day), removes some compensatory entries, and adjusts adjacent holiday dates.
Tests
tests/calendars/test_chinese.py
Adds tests for qingming_date (Chinese/Korean/Vietnamese), qingming estimation behavior, extends winter-solstice test vectors across calendars, and broadens estimated-range checks (1900–2100 / 1901–2099).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • Correctness and completeness of QINGMING_THRESHOLDS (per-calendar mappings and year_mod logic).
    • Interaction between qingming_date reliability flag and tests (1900/1901/2099/2100 bounds).
    • WINTER_SOLSTICE_THRESHOLDS changes (dec_23 variants) and any downstream consumers.
    • Snapshot diffs that merge/shift Tomb‑Sweeping and related observed/compensatory entries.

Possibly related PRs

Suggested reviewers

  • PPsyrius

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the primary change: improving Qingming Festival date calculation in the Chinese calendar implementation, which aligns with the main objective of the changeset.
Description check ✅ Passed The description clearly relates to the changeset, outlining updates to Qingming Festival and Winter Solstice calculations for the 1901-2099 range, with notes about Vietnamese calendar support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59bae73 and 5e4afca.

📒 Files selected for processing (1)
  • tests/calendars/test_chinese.py (4 hunks)
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2631
File: tests/countries/test_sint_maarten.py:62-0
Timestamp: 2025-06-14T21:12:07.224Z
Learning: KJhellico prefers to focus on completing and reviewing the main holiday implementation code before doing detailed reviews of the corresponding test files.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: holidays/countries/south_africa.py:69-75
Timestamp: 2025-09-14T07:26:25.431Z
Learning: When reviewing historical holiday implementations in the vacanza/holidays repository, trust the maintainers' research and implementation decisions for specific historical edge cases, especially when they can provide sources like Wikipedia or other historical documentation that supports unusual or complex date calculation rules during specific time periods.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2537
File: tests/countries/test_finland.py:23-26
Timestamp: 2025-05-09T18:36:09.607Z
Learning: The holidays project prioritizes complete historical coverage in tests, verifying holidays from their first year of observance (e.g., 1853 for Finland) through future projections, rather than using shorter sliding windows.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2777
File: holidays/countries/gambia.py:120-122
Timestamp: 2025-08-03T13:48:11.910Z
Learning: When reviewing holiday implementations in the holidays library, defer to the maintainers' choice of start years for specific holiday policies, as they likely have access to more reliable primary sources and official documentation than what can be found through web searches.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_indonesia.py:221-223
Timestamp: 2025-09-28T05:42:12.777Z
Learning: In tests/countries/test_indonesia.py, the manual set inclusion checks using get_named and years_found for Lunar New Year (test_lunar_new_year) and Vesak Day (test_vesak_day) are intentional and should remain until both holidays get their own `{insert}_no_estimated` flags implemented, rather than using standard harness assertions like assertHolidayName/assertNoHolidayName.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/countries/macau.py:385-396
Timestamp: 2025-03-04T10:06:09.555Z
Learning: The winter solstice calculation in Macau's holiday implementation uses the same approximation method as Hong Kong's implementation and has been verified against the official Macau calendar for years 2017-2025. The method is valid for years 1952-2099.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2530
File: tests/countries/test_andorra.py:23-28
Timestamp: 2025-05-06T21:07:11.577Z
Learning: In the holidays project, test methods for country holidays follow a standard form where year ranges are explicitly recreated in each test method rather than being stored as class variables, to maintain consistency across all country tests.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2653
File: holidays/locale/th/LC_MESSAGES/TW.po:17-21
Timestamp: 2025-06-21T18:06:50.027Z
Learning: KJhellico's username includes a tilde character (~) as part of their nickname (appears as "~Jhellico" in Last-Translator headers), which is intentional formatting and not an error.
📚 Learning: 2025-09-28T05:42:12.777Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_indonesia.py:221-223
Timestamp: 2025-09-28T05:42:12.777Z
Learning: In tests/countries/test_indonesia.py, the manual set inclusion checks using get_named and years_found for Lunar New Year (test_lunar_new_year) and Vesak Day (test_vesak_day) are intentional and should remain until both holidays get their own `{insert}_no_estimated` flags implemented, rather than using standard harness assertions like assertHolidayName/assertNoHolidayName.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-05T04:47:27.213Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-05T06:49:06.217Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2386
File: tests/countries/test_nepal.py:499-536
Timestamp: 2025-04-05T06:49:06.217Z
Learning: In the holidays project, test files follow a dual testing approach: individual methods test specific holidays across multiple years, while comprehensive year-specific tests (e.g., `test_2025`) verify all holidays for a specific year in a single assertion. Both approaches serve different testing purposes and complement each other.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-12T17:16:54.497Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2794
File: tests/calendars/test_julian.py:35-36
Timestamp: 2025-08-12T17:16:54.497Z
Learning: In the vacanza/holidays project calendar tests (Thai, Ethiopian, Julian, etc.), the established testing pattern for validation methods is to use simple for loops like `for year in known_data_dict:` followed by `self.assertEqual(expected, actual)` without using unittest's subTest feature. This pattern is consistently maintained across all calendar test files.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-18T03:19:23.722Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_algeria.py:28-30
Timestamp: 2025-09-18T03:19:23.722Z
Learning: In the vacanza/holidays project, tests now use self.start_year and self.end_year from the TestCase class instead of country-specific aliases (like DZ.start_year) for start_year and end_year references. This approach provides the test framework with better control over test year ranges rather than being tied to specific country start years.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-05-06T21:07:11.577Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2530
File: tests/countries/test_andorra.py:23-28
Timestamp: 2025-05-06T21:07:11.577Z
Learning: In the holidays project, test methods for country holidays follow a standard form where year ranges are explicitly recreated in each test method rather than being stored as class variables, to maintain consistency across all country tests.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-07-02T18:17:53.342Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2608
File: tests/countries/test_saint_vincent_and_the_grenadines.py:162-178
Timestamp: 2025-07-02T18:17:53.342Z
Learning: In the Saint Vincent and the Grenadines holidays implementation, New Year's Day is added without observed rules using `_add_new_years_day()` and should not include observed rule testing in its test method. Only holidays explicitly wrapped with `_add_observed()` have observed behavior.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-11-08T05:09:56.159Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_french_polynesia.py:19-22
Timestamp: 2025-11-08T05:09:56.159Z
Learning: In the vacanza/holidays project's test framework (PR #2881 onwards), the base class CommonCountryTests provides a default test_no_holidays implementation that automatically tests years=start_year - 1 for standard PUBLIC category cases. Individual country test files should only override test_no_holidays when the country supports additional non-PUBLIC categories (GOVERNMENT, WORKDAY, OPTIONAL, etc.) with different start years requiring separate validation.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-06-15T11:52:39.572Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2601
File: tests/countries/test_mongolia.py:128-156
Timestamp: 2025-06-15T11:52:39.572Z
Learning: In the vacanza/holidays project tests, when testing holidays that span multiple consecutive days across many years (like Mongolia's National Festival spanning July 11-13), prefer explicit for loops over complex nested generator expressions with unpacking. The explicit loops are more readable, easier to maintain, and better communicate the testing intent even though the Big O complexity is equivalent.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-14T16:05:55.205Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_iran.py:28-28
Timestamp: 2025-09-14T16:05:55.205Z
Learning: In tests/countries/test_iran.py, using years=(self.start_year - 1, 2102) in the no-holiday test is intentional because Iran uses the Persian Calendar which has specific supported year range constraints, and 2102 represents the upper limit of the Persian Calendar's supported range, not just an arbitrary far-future date.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-04T10:52:41.546Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2398
File: holidays/countries/guinea.py:106-110
Timestamp: 2025-04-04T10:52:41.546Z
Learning: In the Guinea holidays implementation, observed Eid al-Fitr cases are properly covered by the test_eid_al_fitr_day() method, which tests both the regular holiday dates and the observed dates when the holiday falls on a non-working day (for years >= 2023).

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-07-09T21:16:35.145Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2623
File: tests/countries/test_christmas_island.py:136-146
Timestamp: 2025-07-09T21:16:35.145Z
Learning: In Christmas Island's holiday implementation, the test_christmas_day method cannot use assertNoNonObservedHoliday because in some years observed Christmas Day overlaps with Boxing Day when both holidays are moved due to weekend conflicts, causing the standard non-observed holiday check to fail inappropriately.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-04T10:52:41.546Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2398
File: holidays/countries/guinea.py:106-110
Timestamp: 2025-04-04T10:52:41.546Z
Learning: In the Guinea holidays implementation, observed Eid al-Fitr cases are covered by the test_eid_al_fitr_day() method, which tests both regular holiday dates and the observed dates when the holiday falls on a non-working day (for years >= 2023).

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-14T16:03:13.558Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_barbados.py:21-23
Timestamp: 2025-09-14T16:03:13.558Z
Learning: In tests/countries/test_barbados.py, using years_non_observed=range(2000, 2024) is intentional because all observed holiday examples fall within 2001-2023, making this range appropriate for limiting testing to years where observed holidays actually exist in the test data.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-10T13:39:34.625Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_angola.py:22-22
Timestamp: 2025-09-10T13:39:34.625Z
Learning: In the holidays project, the main testing range should always span from start_year to 2050 (or end_year if available). This applies to both the main years parameter and years_non_observed parameter in test setups to maintain consistency across all country tests.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-25T04:28:02.061Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2848
File: tests/countries/test_somalia.py:44-127
Timestamp: 2025-08-25T04:28:02.061Z
Learning: In the holidays library, Islamic holiday tests use `self.no_estimated_holidays = Country(years=years, islamic_show_estimated=False)` as the library-wide standard approach to simplify test cases. This pattern is intentional and preferred over testing estimated labels.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-17T09:07:56.459Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_paraguay.py:134-139
Timestamp: 2025-09-17T09:07:56.459Z
Learning: In the vacanza/holidays project, when testing holidays that start from a specific year (not the country's start_year), the standard pattern is to use `range(specific_year, self.end_year)` for the holiday dates and `assertNoHolidayName(name, range(self.start_year, specific_year))` for the gap period. Using `self.full_range` with year conditions like `if year >= specific_year` is not the established pattern and would be inconsistent with the codebase.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-06-14T10:58:43.636Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2629
File: tests/countries/test_namibia.py:22-23
Timestamp: 2025-06-14T10:58:43.636Z
Learning: In the vacanza/holidays project, country test files consistently use range(start_year, 2050) which intentionally excludes 2050 and stops at 2049. This is a library-wide implementation pattern, not an off-by-one error.

Applied to files:

  • tests/calendars/test_chinese.py
🧬 Code graph analysis (1)
tests/calendars/test_chinese.py (1)
holidays/calendars/chinese.py (2)
  • qingming_date (1397-1415)
  • winter_solstice_date (1417-1435)
🪛 Ruff (0.14.8)
tests/calendars/test_chinese.py

47-47: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


70-70: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


93-93: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


97-97: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


99-99: Use a regular assert instead of unittest-style assertFalse

Replace assertFalse(...) with assert ...

(PT009)


172-172: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)

🔇 Additional comments (2)
tests/calendars/test_chinese.py (2)

26-99: Qingming tests cover the new calendar behavior cleanly

The year/day samples for Chinese, Korean, and Vietnamese calendars plus the estimated-flag checks all line up with the qingming_date (date, is_estimated) contract and the documented 1901–2099 reliability window. Using simple for loops with self.assertEqual/self.assertTrue/self.assertFalse also matches the established calendar-test style in this repo, so this block looks good to keep as-is.
Based on learnings, this follows the existing calendar test pattern.


101-174: Winter solstice tests nicely extend coverage and match the new reliability bounds

The added early-1900s year/day pairs for Chinese, Korean, and Vietnamese calendars, along with the boundary checks for the estimated flag (1900 & 2100 as estimated; 1901 & 2099 as non-estimated), are consistent with the winter_solstice_date implementation and its 1901–2099 reliability note. The structure mirrors the Qingming tests and stays in line with the calendar-test conventions, so this whole section looks solid.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (8bb2009) to head (5e4afca).
⚠️ Report is 4 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #3119   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          306       306           
  Lines        18150     18155    +5     
  Branches      2300      2301    +1     
=========================================
+ Hits         18150     18155    +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
holidays/groups/chinese.py (1)

196-205: Optional: route Dongzhi through _add_chinese_calendar_holiday for consistency.

If you want show_estimated to affect Dongzhi the same way it now does for Qingming and other lunisolar holidays, consider reusing _add_chinese_calendar_holiday() here:

-        return self._add_holiday(name, self._dongzhi_festival)
+        return self._add_chinese_calendar_holiday(
+            name, self._chinese_calendar.winter_solstice_date(self._year)
+        )

This keeps behaviour unchanged for reliable years but would attach the estimation label automatically when outside the trusted winter‑solstice range.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bb2009 and b2f9010.

📒 Files selected for processing (10)
  • holidays/calendars/chinese.py (3 hunks)
  • holidays/groups/chinese.py (3 hunks)
  • snapshots/countries/CN_COMMON.json (3 hunks)
  • snapshots/countries/HK_COMMON.json (6 hunks)
  • snapshots/countries/KP_COMMON.json (3 hunks)
  • snapshots/countries/MO_COMMON.json (3 hunks)
  • snapshots/countries/MO_I.json (3 hunks)
  • snapshots/countries/MO_M.json (3 hunks)
  • snapshots/countries/TW_COMMON.json (3 hunks)
  • tests/calendars/test_chinese.py (4 hunks)
🧰 Additional context used
🧠 Learnings (44)
📓 Common learnings
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2631
File: tests/countries/test_sint_maarten.py:62-0
Timestamp: 2025-06-14T21:12:07.224Z
Learning: KJhellico prefers to focus on completing and reviewing the main holiday implementation code before doing detailed reviews of the corresponding test files.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: holidays/countries/south_africa.py:69-75
Timestamp: 2025-09-14T07:26:25.431Z
Learning: When reviewing historical holiday implementations in the vacanza/holidays repository, trust the maintainers' research and implementation decisions for specific historical edge cases, especially when they can provide sources like Wikipedia or other historical documentation that supports unusual or complex date calculation rules during specific time periods.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2777
File: holidays/countries/gambia.py:120-122
Timestamp: 2025-08-03T13:48:11.910Z
Learning: When reviewing holiday implementations in the holidays library, defer to the maintainers' choice of start years for specific holiday policies, as they likely have access to more reliable primary sources and official documentation than what can be found through web searches.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2354
File: holidays/countries/fiji.py:146-159
Timestamp: 2025-03-19T16:54:58.657Z
Learning: In the holidays library implementation, explicit holiday dates (like Diwali in Fiji) are only defined for historical years with official sources (2016-2025). Future dates beyond the explicitly defined range are automatically calculated by methods like `_add_diwali`, which provide approximations when official dates aren't yet available.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2951
File: tests/calendars/test_thai.py:0-0
Timestamp: 2025-09-21T05:16:38.578Z
Learning: In holidays/calendars/thai.py, the `buddhist_sabbath_dates` method in `_ThaiLunisolar` is independent of calendar type (THAI_CALENDAR vs KHMER_CALENDAR) and calculates Buddhist Sabbath dates consistently regardless of which calendar is being used.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2537
File: tests/countries/test_finland.py:23-26
Timestamp: 2025-05-09T18:36:09.607Z
Learning: The holidays project prioritizes complete historical coverage in tests, verifying holidays from their first year of observance (e.g., 1853 for Finland) through future projections, rather than using shorter sliding windows.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2794
File: holidays/countries/ethiopia.py:63-63
Timestamp: 2025-08-12T18:40:16.160Z
Learning: Ethiopian Epiphany (Timkat) date calculation correctly uses `is_ethiopian_leap_year(self._year - 1)` in the `_add_epiphany_day` helper in `holidays/groups/christian.py`. Since Epiphany occurs in January and belongs to the Ethiopian year that started in the previous Gregorian year, it checks Ethiopian leap year rules for `self._year - 1`. This is the proper approach, not using Gregorian leap year rules.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/countries/macau.py:385-396
Timestamp: 2025-03-04T10:06:09.555Z
Learning: The winter solstice calculation in Macau's holiday implementation uses the same approximation method as Hong Kong's implementation and has been verified against the official Macau calendar for years 2017-2025. The method is valid for years 1952-2099.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2843
File: holidays/countries/burundi.py:15-16
Timestamp: 2025-08-21T05:56:33.276Z
Learning: In the holidays library, when importing Gregorian month constants from holidays.calendars.gregorian, only import the months that are actually used in the date data. For example, if Islamic holiday dates only reference JUN, JUL, SEP, OCT, then only import those specific constants rather than importing additional unused months.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2653
File: holidays/locale/th/LC_MESSAGES/TW.po:17-21
Timestamp: 2025-06-21T18:06:50.027Z
Learning: KJhellico's username includes a tilde character (~) as part of their nickname (appears as "~Jhellico" in Last-Translator headers), which is intentional formatting and not an error.
📚 Learning: 2025-04-03T05:59:57.480Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2407
File: snapshots/countries/TL_COMMON.json:7-7
Timestamp: 2025-04-03T05:59:57.480Z
Learning: In the holidays project, snapshot files (like snapshots/countries/TL_COMMON.json) are auto-generated when running `make snapshot` and should not be manually edited. Semicolons (;) in holiday entries are used as separators when multiple holidays occur on the same date.

Applied to files:

  • snapshots/countries/KP_COMMON.json
  • snapshots/countries/CN_COMMON.json
  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/TW_COMMON.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-03-13T07:48:12.724Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2349
File: holidays/locale/en_US/LC_MESSAGES/TW.po:56-57
Timestamp: 2025-03-13T07:48:12.724Z
Learning: The term "民族掃墓節" in Taiwan is officially translated as "Tomb Sweeping Day" according to the DGPA (Directorate-General of Personnel Administration), with "Tomb-Sweeping Day" (hyphenated version) being used in the holidays library for consistency with China, Macau, and Hong Kong implementations.

Applied to files:

  • snapshots/countries/CN_COMMON.json
  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-08-31T09:54:22.093Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2874
File: tests/countries/test_taiwan.py:379-381
Timestamp: 2025-08-31T09:54:22.093Z
Learning: In Taiwan's holiday system, some holidays like Women's Day can appear in multiple categories simultaneously. Women's Day appears in the WORKDAY category for regular March 8th dates but also has special observed dates in the OPTIONAL category (1998-2000) when it was moved before Tomb-Sweeping Day. The test cases correctly reflect this dual-category behavior.

Applied to files:

  • snapshots/countries/CN_COMMON.json
  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/TW_COMMON.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-09-17T15:16:16.192Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2944
File: holidays/countries/myanmar.py:183-191
Timestamp: 2025-09-17T15:16:16.192Z
Learning: The special_public_holidays formatting pattern in the holidays codebase follows a consistent convention: single entries per year use flat tuple format like `2024: (MONTH, DAY, name)`, while multiple entries per year use tuple-of-tuples format like `2024: ((MONTH, DAY, name), (MONTH, DAY, name))`. This pattern is used consistently across all countries.

Applied to files:

  • snapshots/countries/CN_COMMON.json
  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/TW_COMMON.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-09-17T15:15:24.269Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2944
File: holidays/countries/myanmar.py:112-121
Timestamp: 2025-09-17T15:15:24.269Z
Learning: The Myanmar government's "continuous public days for 2024-2025" policy specifically covers Tabaung and Tazaungmon full moon days by bridging gaps with weekends, but does not apply to Myanmar New Year (Thingyan) extra days, which follow a separate policy that correctly uses `self._year >= 2024`.

Applied to files:

  • snapshots/countries/CN_COMMON.json
  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/TW_COMMON.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-04-03T16:58:27.175Z
Learnt from: Wasif-Shahzad
Repo: vacanza/holidays PR: 2409
File: holidays/countries/qatar.py:27-46
Timestamp: 2025-04-03T16:58:27.175Z
Learning: In the holidays library, method names like `_add_holiday_2nd_tue_of_feb()` and `_add_holiday_1st_sun_of_mar()` use calendar constants internally through parent class implementations even when these constants don't appear directly in the file. Removing imports that seem unused based on a simple text search could break functionality.

Applied to files:

  • holidays/groups/chinese.py
  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-11T10:14:28.517Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2794
File: holidays/groups/christian.py:328-343
Timestamp: 2025-08-11T10:14:28.517Z
Learning: For Ethiopian holidays in the `holidays/groups/christian.py` file, docstring wording should maintain source-accurate phrasing (e.g., "in coincidence of" for Ethiopian New Year/Enkutatash), even when it might read awkwardly in English, to ensure consistency with official Ethiopian documentation.

Applied to files:

  • holidays/groups/chinese.py
📚 Learning: 2025-08-21T05:56:33.276Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2843
File: holidays/countries/burundi.py:15-16
Timestamp: 2025-08-21T05:56:33.276Z
Learning: In the holidays library, when importing Gregorian month constants from holidays.calendars.gregorian, only import the months that are actually used in the date data. For example, if Islamic holiday dates only reference JUN, JUL, SEP, OCT, then only import those specific constants rather than importing additional unused months.

Applied to files:

  • holidays/groups/chinese.py
  • holidays/calendars/chinese.py
📚 Learning: 2025-04-03T16:58:27.175Z
Learnt from: Wasif-Shahzad
Repo: vacanza/holidays PR: 2409
File: holidays/countries/qatar.py:27-46
Timestamp: 2025-04-03T16:58:27.175Z
Learning: In the holidays library, method names like `_add_holiday_2nd_tue_of_feb()` and `_add_holiday_1st_sun_of_mar()` use calendar constants like FEB, TUE, MAR, and SUN internally through parent class implementations even when these constants don't appear directly in the file.

Applied to files:

  • holidays/groups/chinese.py
📚 Learning: 2025-06-24T17:26:17.728Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2654
File: snapshots/countries/CV_RS.json:471-478
Timestamp: 2025-06-24T17:26:17.728Z
Learning: Snapshot files in the holidays library (like those in snapshots/countries/) are generated automatically and should not be manually edited. Any issues with snapshot content should be addressed in the source code that generates them, not in the snapshot files themselves.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-03-05T02:35:03.298Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/countries/macau.py:278-377
Timestamp: 2025-03-05T02:35:03.298Z
Learning: For Macau holiday implementations, it's preferable to maintain separate methods for different holiday categories (MANDATORY, GOVERNMENT, PUBLIC) as they are based on different sets of laws, making the code easier to maintain despite having multiple year-based conditionals.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-03-04T11:41:56.389Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/countries/macau.py:284-366
Timestamp: 2025-03-04T11:41:56.389Z
Learning: For Macau holidays implementation, maintaining separate methods for each holiday category (PUBLIC, MANDATORY, GOVERNMENT) is preferred because these categories are based on different sets of laws and have distinct historical evolution.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-09-28T05:42:12.777Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_indonesia.py:221-223
Timestamp: 2025-09-28T05:42:12.777Z
Learning: In tests/countries/test_indonesia.py, the manual set inclusion checks using get_named and years_found for Lunar New Year (test_lunar_new_year) and Vesak Day (test_vesak_day) are intentional and should remain until both holidays get their own `{insert}_no_estimated` flags implemented, rather than using standard harness assertions like assertHolidayName/assertNoHolidayName.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/TW_COMMON.json
  • snapshots/countries/MO_I.json
  • tests/calendars/test_chinese.py
📚 Learning: 2025-07-09T20:27:37.760Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2623
File: holidays/countries/christmas_island.py:110-112
Timestamp: 2025-07-09T20:27:37.760Z
Learning: In Christmas Island, ANZAC Day (April 25) follows the same observed holiday rules as other holidays, using the SAT_SUN_TO_NEXT_MON rule to move to Monday when it falls on a weekend. The implementation correctly uses `_add_observed` wrapper around `_add_anzac_day`.

Applied to files:

  • snapshots/countries/HK_COMMON.json
📚 Learning: 2025-07-10T03:36:16.461Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2706
File: holidays/countries/cayman_islands.py:80-97
Timestamp: 2025-07-10T03:36:16.461Z
Learning: In the holidays library, date dictionaries that map years to specific dates (like queens_birthday_dates, spring_bank_dates, thanksgiving_day_dates, etc.) are typically defined within the _populate_public_holidays method rather than as module-level constants. This is the established library-wide pattern seen across multiple country implementations including United Kingdom, United States, Sri Lanka, and others.

Applied to files:

  • snapshots/countries/HK_COMMON.json
📚 Learning: 2025-03-19T16:54:58.657Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2354
File: holidays/countries/fiji.py:146-159
Timestamp: 2025-03-19T16:54:58.657Z
Learning: In the holidays library implementation, explicit holiday dates (like Diwali in Fiji) are only defined for historical years with official sources (2016-2025). Future dates beyond the explicitly defined range are automatically calculated by methods like `_add_diwali`, which provide approximations when official dates aren't yet available.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-08-31T09:54:07.868Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2874
File: tests/countries/test_taiwan.py:347-349
Timestamp: 2025-08-31T09:54:07.868Z
Learning: In Taiwan's holiday implementation, Children's Day (兒童節) appears in multiple categories simultaneously: Optional holidays (1998-2000 via special_optional_holidays_observed for observed date handling), Workday holidays (1998-2010), and Public holidays (2011+). The Optional category includes observed date logic for 1998-2000 that moves Children's Day to April 3rd when April 4th falls on Sunday.

Applied to files:

  • snapshots/countries/HK_COMMON.json
  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-06-18T10:26:50.180Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.180Z
Learning: In the France holidays implementation, the _populate_subdiv_57_public_holidays() (Moselle) and _populate_subdiv_6ae_public_holidays() (Alsace) methods are functionally identical, both adding Good Friday (≥1893) and Saint Stephen's Day (≥1892) with the same legal references from August 16th, 1892. Therefore, for the deprecated "Alsace-Moselle" subdivision, calling either method produces the same result.

Applied to files:

  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-03-04T14:42:43.024Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".

Applied to files:

  • snapshots/countries/MO_COMMON.json
  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-11-08T05:09:56.159Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_french_polynesia.py:19-22
Timestamp: 2025-11-08T05:09:56.159Z
Learning: In the vacanza/holidays project's test framework (PR #2881 onwards), the base class CommonCountryTests provides a default test_no_holidays implementation that automatically tests years=start_year - 1 for standard PUBLIC category cases. Individual country test files should only override test_no_holidays when the country supports additional non-PUBLIC categories (GOVERNMENT, WORKDAY, OPTIONAL, etc.) with different start years requiring separate validation.

Applied to files:

  • snapshots/countries/MO_COMMON.json
📚 Learning: 2025-06-16T12:28:31.641Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2632
File: holidays/countries/solomon_islands.py:95-98
Timestamp: 2025-06-16T12:28:31.641Z
Learning: Library-wide holiday patterns and their optimizations should be handled at the base class level (like InternationalHolidays) rather than documenting workarounds in individual country modules. This maintains separation of concerns and avoids documentation duplication.

Applied to files:

  • snapshots/countries/MO_COMMON.json
📚 Learning: 2025-09-14T16:05:55.205Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_iran.py:28-28
Timestamp: 2025-09-14T16:05:55.205Z
Learning: In tests/countries/test_iran.py, using years=(self.start_year - 1, 2102) in the no-holiday test is intentional because Iran uses the Persian Calendar which has specific supported year range constraints, and 2102 represents the upper limit of the Persian Calendar's supported range, not just an arbitrary far-future date.

Applied to files:

  • holidays/calendars/chinese.py
  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-08T21:52:45.289Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2763
File: holidays/groups/mandaean.py:58-69
Timestamp: 2025-08-08T21:52:45.289Z
Learning: HolidayBase in the holidays library has a default end_year = 2100 (defined as DEFAULT_END_YEAR in holidays/constants.py), which is automatically inherited by all country classes unless explicitly overridden.

Applied to files:

  • holidays/calendars/chinese.py
📚 Learning: 2025-04-08T14:50:15.325Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2437
File: holidays/calendars/tibetan.py:805-810
Timestamp: 2025-04-08T14:50:15.325Z
Learning: The standard behavior for calendar date methods in the holidays library is to return `(None, True)` when a requested year is not found in the date dictionary, rather than raising an exception or requiring documentation for out-of-range years.

Applied to files:

  • holidays/calendars/chinese.py
📚 Learning: 2025-03-29T15:15:05.919Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2354
File: holidays/countries/fiji.py:171-183
Timestamp: 2025-03-29T15:15:05.919Z
Learning: In the Fiji holidays implementation, the maintainers are aware of the need to extend the MAWLID_DATES dictionary beyond 2025 when future official references become available, and will do so when appropriate. No suggestions about extending this dictionary should be made in future reviews.

Applied to files:

  • snapshots/countries/MO_M.json
  • snapshots/countries/MO_I.json
📚 Learning: 2025-06-18T10:12:57.419Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.419Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.

Applied to files:

  • snapshots/countries/MO_M.json
📚 Learning: 2025-03-04T14:38:15.029Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.

Applied to files:

  • snapshots/countries/MO_M.json
📚 Learning: 2025-03-04T10:06:57.171Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.

Applied to files:

  • snapshots/countries/MO_M.json
📚 Learning: 2025-08-31T09:54:07.868Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2874
File: tests/countries/test_taiwan.py:347-349
Timestamp: 2025-08-31T09:54:07.868Z
Learning: In Taiwan's holiday implementation, Children's Day (兒童節) appears in multiple categories simultaneously: Optional holidays (1998-2000), Workday holidays (1998-2010), and Public holidays (2011+). The Optional category includes observed date logic for 1998-2000 that moves Children's Day to April 3rd when April 4th falls on Sunday.

Applied to files:

  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-03-13T15:17:45.519Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2349
File: tests/countries/test_taiwan.py:0-0
Timestamp: 2025-03-13T15:17:45.519Z
Learning: For Taiwan's holiday system, different categories (GOVERNMENT, OPTIONAL, SCHOOL, WORKDAY) have distinct uses and contexts, justifying separate instances rather than parameterization in tests.

Applied to files:

  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-03-13T07:50:10.598Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2349
File: snapshots/countries/TW_COMMON.json:9-12
Timestamp: 2025-03-13T07:50:10.598Z
Learning: JSON files in the `snapshots/` directory (like `snapshots/countries/TW_COMMON.json`) are automatically generated by the `make snapshot` command and not meant to be manually edited.

Applied to files:

  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-03-19T16:53:00.375Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2354
File: holidays/countries/fiji.py:185-188
Timestamp: 2025-03-19T16:53:00.375Z
Learning: In the Fiji holidays implementation, the `special_public_holidays_observed` dictionary in `FijiStaticHolidays` is only used for exceptions to the normal observance rules, not for documenting all holidays. Only 2019's Constitution Day needed a special entry as it didn't follow the standard patterns.

Applied to files:

  • snapshots/countries/TW_COMMON.json
📚 Learning: 2025-04-05T06:49:06.217Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2386
File: tests/countries/test_nepal.py:499-536
Timestamp: 2025-04-05T06:49:06.217Z
Learning: In the holidays project, test files follow a dual testing approach: individual methods test specific holidays across multiple years, while comprehensive year-specific tests (e.g., `test_2025`) verify all holidays for a specific year in a single assertion. Both approaches serve different testing purposes and complement each other.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-05T04:47:27.213Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-12T17:16:54.497Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2794
File: tests/calendars/test_julian.py:35-36
Timestamp: 2025-08-12T17:16:54.497Z
Learning: In the vacanza/holidays project calendar tests (Thai, Ethiopian, Julian, etc.), the established testing pattern for validation methods is to use simple for loops like `for year in known_data_dict:` followed by `self.assertEqual(expected, actual)` without using unittest's subTest feature. This pattern is consistently maintained across all calendar test files.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-18T03:19:23.722Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_algeria.py:28-30
Timestamp: 2025-09-18T03:19:23.722Z
Learning: In the vacanza/holidays project, tests now use self.start_year and self.end_year from the TestCase class instead of country-specific aliases (like DZ.start_year) for start_year and end_year references. This approach provides the test framework with better control over test year ranges rather than being tied to specific country start years.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-07-09T21:16:35.145Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2623
File: tests/countries/test_christmas_island.py:136-146
Timestamp: 2025-07-09T21:16:35.145Z
Learning: In Christmas Island's holiday implementation, the test_christmas_day method cannot use assertNoNonObservedHoliday because in some years observed Christmas Day overlaps with Boxing Day when both holidays are moved due to weekend conflicts, causing the standard non-observed holiday check to fail inappropriately.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-04T10:52:41.546Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2398
File: holidays/countries/guinea.py:106-110
Timestamp: 2025-04-04T10:52:41.546Z
Learning: In the Guinea holidays implementation, observed Eid al-Fitr cases are properly covered by the test_eid_al_fitr_day() method, which tests both the regular holiday dates and the observed dates when the holiday falls on a non-working day (for years >= 2023).

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-04-04T10:52:41.546Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2398
File: holidays/countries/guinea.py:106-110
Timestamp: 2025-04-04T10:52:41.546Z
Learning: In the Guinea holidays implementation, observed Eid al-Fitr cases are covered by the test_eid_al_fitr_day() method, which tests both regular holiday dates and the observed dates when the holiday falls on a non-working day (for years >= 2023).

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-14T16:03:13.558Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_barbados.py:21-23
Timestamp: 2025-09-14T16:03:13.558Z
Learning: In tests/countries/test_barbados.py, using years_non_observed=range(2000, 2024) is intentional because all observed holiday examples fall within 2001-2023, making this range appropriate for limiting testing to years where observed holidays actually exist in the test data.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-08-25T04:28:02.061Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2848
File: tests/countries/test_somalia.py:44-127
Timestamp: 2025-08-25T04:28:02.061Z
Learning: In the holidays library, Islamic holiday tests use `self.no_estimated_holidays = Country(years=years, islamic_show_estimated=False)` as the library-wide standard approach to simplify test cases. This pattern is intentional and preferred over testing estimated labels.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-11-28T02:24:17.418Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 3088
File: tests/countries/test_gabon.py:88-110
Timestamp: 2025-11-28T02:24:17.418Z
Learning: For Gabon's holiday implementation (tests/countries/test_gabon.py), all Islamic holiday dates are currently estimates. Therefore, the correct test pattern is to use assertIslamicNoEstimatedHolidayName for both specific known dates and the full range (e.g., test_eid_al_fitr and test_eid_al_adha), rather than using assertHolidayName for specific dates followed by assertIslamicNoEstimatedHolidayName for the range.

Applied to files:

  • tests/calendars/test_chinese.py
📚 Learning: 2025-09-03T16:49:35.246Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_argentina.py:375-375
Timestamp: 2025-09-03T16:49:35.246Z
Learning: In the holidays library, national holiday tests use self.full_range (or similar comprehensive year ranges) even when explicit test dates only show modern observance. This is intentional for correctness and comprehensive coverage, unlike subdivision-specific holidays which have explicit year boundaries based on known start dates.

Applied to files:

  • tests/calendars/test_chinese.py
🧬 Code graph analysis (2)
holidays/groups/chinese.py (1)
holidays/calendars/chinese.py (1)
  • qingming_date (1397-1415)
tests/calendars/test_chinese.py (1)
holidays/calendars/chinese.py (2)
  • qingming_date (1397-1415)
  • winter_solstice_date (1417-1435)
🪛 Ruff (0.14.8)
holidays/calendars/chinese.py

1309-1325: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

tests/calendars/test_chinese.py

47-47: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


70-70: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


93-93: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


166-166: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


168-168: Use a regular assert instead of unittest-style assertFalse

Replace assertFalse(...) with assert ...

(PT009)


172-172: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


174-174: Use a regular assert instead of unittest-style assertFalse

Replace assertFalse(...) with assert ...

(PT009)

⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test Python 3.12 on windows-latest
  • GitHub Check: Test Python 3.13 on windows-latest
  • GitHub Check: Test Python 3.11 on windows-latest
  • GitHub Check: Test Python 3.10 on windows-latest
  • GitHub Check: Test Python 3.14 on windows-latest
🔇 Additional comments (13)
snapshots/countries/CN_COMMON.json (1)

1504-1523: Qingming/Tomb‑Sweeping snapshot alignment looks good.

2042, 2046, and 2050 now use a single 04‑04 “Tomb‑Sweeping Day” entry, matching the centralized qingming_date logic and removing the old 04‑05/observed variants. No duplicate dates or label inconsistencies around these years.

Also applies to: 1585-1603, 1665-1687

snapshots/countries/KP_COMMON.json (1)

879-899: Cheongmyeong dates now match calendar‑specific Qingming rules.

The 2013 (→ 04‑05), 2046 (→ 04‑04), and 2050 (→ 04‑04) Cheongmyeong entries are cleanly updated with no duplicate dates and are consistent with the new per‑calendar qingming_date thresholds. Snapshot structure remains intact.

Also applies to: 1594-1615, 1681-1702

snapshots/countries/MO_COMMON.json (1)

1497-1510: Macau Tomb‑Sweeping adjustments are consistent with the new Qingming logic.

  • 2042 cleanly merges Qingming onto the existing Good Friday date (04‑04) and keeps Easter/compensatory days ordered.
  • 2046 and 2050 shift Tomb‑Sweeping to 04‑04 with no stray 04‑05 entries.
    All changes fit MO’s pattern of combining holidays on the same date and match the CN snapshot dates.

Also applies to: 1608-1621, 1721-1736

holidays/groups/chinese.py (1)

38-43: Qingming now correctly delegates to the central calendar helper.

_qingming_festival and _add_qingming_festival() both use self._chinese_calendar.qingming_date(self._year), and _add_qingming_festival() feeds the full (date, estimated) tuple into _add_chinese_calendar_holiday(). This removes duplicated date logic, respects the new 1901–2099 reliability window, and keeps estimation labelling consistent with other Chinese‑calendar holidays.

Also applies to: 220-230

snapshots/countries/MO_I.json (1)

1520-1521: MO snapshots track new Qingming/Tomb‑Sweeping logic correctly

The 2042/2046/2050 adjustments (merging Good Friday with Tomb‑Sweeping Day and shifting Tomb‑Sweeping Day to 04‑04) look consistent with the new Chinese calendar rules and with the wider snapshot pattern in this PR. Since snapshots are auto‑generated via make snapshot, there’s nothing to hand‑tune here from a review perspective.

Based on learnings, these entries should continue to be maintained only via code changes plus make snapshot, not by editing this JSON directly.

Also applies to: 1634-1634, 1745-1745

snapshots/countries/TW_COMMON.json (1)

1210-1211: TW snapshot updates align Children’s Day + Tomb‑Sweeping with new Qingming dates

The 2042/2046/2050 mappings that put “Children's Day; Tomb‑Sweeping Day” on 04‑04 and use nearby observed Children’s Day entries look coherent with Taiwan’s overlapping‑holiday rules and the new Qingming calculation. Given these JSONs are produced by make snapshot, this looks like the expected downstream effect of the calendar change.

Based on learnings, any future tweaks should go through the calendar/source code and regenerated snapshots, not manual edits.

Also applies to: 1324-1325, 1439-1440

snapshots/countries/HK_COMMON.json (1)

203-204: HK snapshot shifts for Tomb‑Sweeping Day match the new calendar rules

The Hong Kong entries that now:

  • Combine “Good Friday; Tomb‑Sweeping Day” (e.g. 2042‑04‑04),
  • And normalize Tomb‑Sweeping Day to 04‑04 in later years (2046, 2050) with appropriate observed/adjacent days,

are consistent with the shared Chinese‑calendar qingming_date changes and with corresponding CN/MO/TW snapshots. Given these JSONs are auto‑generated via make snapshot, they look like the expected downstream data refresh, not something to hand‑edit.

Based on learnings, any future discrepancies here should be fixed in the calendar logic and then regenerated.

Also applies to: 268-268, 335-335, 1591-1592, 1669-1669, 1739-1739

snapshots/countries/MO_M.json (1)

1519-1520: LGTM - Snapshot correctly reflects improved Qingming calculation.

The Tomb-Sweeping Day date adjustments (2042, 2046, 2050) are systematic outputs from the enhanced Qingming Festival calculation method introduced in this PR. The changes align with the extended reliability range (1901-2099) and properly reflect the improved accuracy.

Also applies to: 1633-1633, 1744-1744

tests/calendars/test_chinese.py (5)

26-47: Strong test coverage for Chinese calendar Qingming dates.

The test spans the reliable calculation range (1901-2099) with representative year samples covering different modulo-4 values and threshold transitions. Good alignment with the implementation's threshold-based logic.


49-93: Comprehensive cross-calendar Qingming validation.

Both Korean and Vietnamese calendar tests follow the established pattern and provide thorough coverage across the reliable year range. The calendar-specific threshold differences are properly exercised through the year/day test pairs.


97-99: Good expansion of Winter Solstice test coverage.

The added test cases for early 20th century years (1906-1922) properly validate the extended reliability range (1901-2099) mentioned in the PR objectives. This ensures the improved calculation accuracy extends to the earlier boundary years.

Also applies to: 120-122, 142-144


170-174: Proper validation of Qingming estimation flag boundaries.

The test correctly verifies that years outside the reliable range (1900, 2100) are marked as estimated, while boundary years within the range (1901, 2099) are not. This aligns perfectly with the PR's stated reliability improvements.


165-169: Consistent reliability range across solar terms.

The updated boundary years (1900/2100 for estimated, 1901/2099 for reliable) align Winter Solstice testing with the Qingming tests and the PR's extended reliability range. Good consistency.

PPsyrius
PPsyrius previously approved these changes Dec 10, 2025
Copy link
Copy Markdown
Collaborator

@PPsyrius PPsyrius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🗓️

@sonarqubecloud
Copy link
Copy Markdown

@arkid15r arkid15r enabled auto-merge December 11, 2025 19:19
Copy link
Copy Markdown
Collaborator

@arkid15r arkid15r left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@arkid15r arkid15r added this pull request to the merge queue Dec 11, 2025
Merged via the queue into vacanza:dev with commit 6538b23 Dec 11, 2025
81 of 157 checks passed
@KJhellico KJhellico deleted the upd-calendar-qingming branch December 15, 2025 00:26
@KJhellico KJhellico mentioned this pull request Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants