-
-
Notifications
You must be signed in to change notification settings - Fork 561
Extend Chinese Lunisolar calendar support #2488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@KJhellico has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 26 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
Summary by CodeRabbit
Summary by CodeRabbit
WalkthroughThis update introduces multi-calendar support for lunisolar holidays, specifically adding Korean and Vietnamese calendar handling alongside the existing Chinese implementation. Holiday date dictionaries are extended or corrected for accuracy, including new entries for the year 2100 across Buddhist, Hindu, and lunisolar calendars. South Korea and Vietnam country modules are refactored to leverage the new calendar selection mechanism, removing legacy hardcoded classes. The lunar calendar generator script and Vietnamese holiday snapshots are updated for expanded year coverage and corrected dates. New unit tests are added to validate calendar selection logic and holiday calculation accuracy. Changes
Suggested labels
Suggested reviewers
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## dev #2488 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 214 214
Lines 13527 13543 +16
Branches 1928 1929 +1
=========================================
+ Hits 13527 13543 +16 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🔭 Outside diff range comments (1)
holidays/countries/south_korea.py (1)
89-96: 🧹 Nitpick (assertive)Calendar variant injected correctly; minor future‑proofing tip.
Works with the new constructor. Ifshow_estimatedever matters for Korea, expose it viakwargs.setdefaultto avoid another touch‑up.- ChineseCalendarHolidays.__init__(self, calendar=KOREAN_CALENDAR) + ChineseCalendarHolidays.__init__( + self, + calendar=KOREAN_CALENDAR, + # show_estimated can be toggled in one place later + )
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (12)
holidays/calendars/buddhist.py(4 hunks)holidays/calendars/chinese.py(9 hunks)holidays/calendars/hindu.py(3 hunks)holidays/countries/indonesia.py(2 hunks)holidays/countries/south_korea.py(2 hunks)holidays/countries/vietnam.py(2 hunks)holidays/groups/chinese.py(2 hunks)scripts/calendar/asian_generator.py(8 hunks)snapshots/countries/ID_COMMON.json(1 hunks)snapshots/countries/VN_COMMON.json(8 hunks)tests/calendars/test_chinese.py(1 hunks)tests/countries/test_vietnam.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
holidays/countries/indonesia.py (1)
holidays/groups/chinese.py (1)
ChineseCalendarHolidays(21-266)
holidays/groups/chinese.py (1)
holidays/calendars/chinese.py (1)
_ChineseLunisolar(31-1349)
holidays/countries/south_korea.py (1)
holidays/groups/chinese.py (1)
ChineseCalendarHolidays(21-266)
holidays/calendars/chinese.py (4)
holidays/calendars/buddhist.py (1)
_get_holiday(430-434)holidays/calendars/hindu.py (1)
_get_holiday(1227-1231)holidays/calendars/islamic.py (1)
_get_holiday(3801-3806)holidays/holiday_base.py (1)
get(967-990)
🔇 Additional comments (37)
scripts/calendar/asian_generator.py (10)
43-44: Correctly updated lunar month data for precise date calculations.The hexadecimal value correction in G_LUNAR_MONTH_DAYS array ensures accurate lunar date calculations, which is essential for determining holidays in the Chinese lunisolar calendar.
57-59: Verified lunar data corrections around 1920.These hex value corrections align with historical lunar calendar data, improving accuracy for this period.
63-63: Corrected critical lunar data for 1920.The hex value update ensures correct lunar month length calculations for this year.
132-132: Fixed lunar month data for 1990.This correction ensures accurate lunar-to-gregorian date conversions for holidays in this time period.
168-168: Corrected lunar data for 2020s period.The updated hex value improves accuracy for modern holiday date calculations.
232-232: Fixed lunar data for 2090.This correction is important for far-future holiday date calculations.
242-243: Corrected lunar data for year 2100.These hex value updates complete the accurate representation of the lunisolar calendar through 2100.
247-253: Extended calendar end year and adjusted date boundaries.The extension from 2099 to 2100 with corresponding end date adjustments aligns with the PR objective to extend date support up to year 2100.
359-362: Added time zone documentation for regional calendar variants.This documentation clearly maps the UTC offsets for different regions, providing context for the three variants (Vietnamese, Chinese, Korean) mentioned in the PR objectives.
390-390: Extended date processing range to match new boundary.The update to process years through 2100 ensures complete coverage for the extended date range.
holidays/calendars/buddhist.py (3)
149-149: Fixed Vesak holiday date for 2025.Updating from May 11 to May 12 reflects the corrected lunisolar calendar calculations.
224-224: Added Vesak holiday support for year 2100.This addition properly extends Buddhist calendar holiday support to match the extended calendar range in the generator.
427-427: Added Vesak May date for year 2100.This addition correctly extends the alternative Vesak calculation used by some countries through 2100.
snapshots/countries/ID_COMMON.json (1)
1200-1200: Corrected Lunar New Year date for 2030 in Indonesia.The date change from February 3rd to February 2nd aligns with using the Vietnamese calendar variant (UTC+7) for Indonesia, as specified in the PR objectives.
tests/countries/test_vietnam.py (1)
72-72: Corrected Hung Kings' Day date for 2009.The date change from April 5th to April 4th ensures the test aligns with the Vietnamese calendar variant calculations, maintaining test consistency with the implementation changes.
tests/calendars/test_chinese.py (1)
13-20: Well-structured test for calendar validation.This test effectively verifies that the
_ChineseLunisolarclass properly rejects invalid calendar types by raising aValueError. This supports the multi-calendar enhancement that adds regional calendar variants (Chinese, Korean, Vietnamese).holidays/countries/indonesia.py (2)
20-20: Appropriate import for the Vietnam calendar constant.Adding the import of
VIETNAM_CALENDARfrom the Chinese calendars module supports the use of the correct regional calendar variant.
76-78: Correct calendar specification for Indonesia.Using the
VIETNAM_CALENDARparameter is appropriate since Indonesia shares the UTC+7 timezone with Vietnam, as mentioned in the PR objectives. This ensures that Chinese lunar calendar holidays in Indonesia will use the correct regional variant.holidays/calendars/hindu.py (4)
138-138: Date correction for historical accuracy.The change corrects the Diwali date for 1914, aligning with the PR's focus on improving calendar accuracy.
144-144: Date correction for historical accuracy.The change corrects the Diwali date for 1920, contributing to better historical precision.
324-324: Extended date support through 2100.Adding the Diwali date for 2100 meets the PR objective to extend calendar date support.
1185-1185: Extended date support through 2100.Adding the Thaipusam date for 2100 completes the calendar extension and ensures consistency across all holiday types.
snapshots/countries/VN_COMMON.json (9)
123-126: Calendar date correction for Vietnamese lunar calendar.These date adjustments for Lunar New Year 1965 align with the Vietnamese calendar variant (UTC+7), ensuring accurate holiday calculations specific to Vietnam.
147-150: Calendar date correction for Vietnamese lunar calendar.These adjustments for Lunar New Year 1968 ensure consistency with the Vietnamese calendar calculations.
155-158: Calendar date correction for Vietnamese lunar calendar.These adjustments for Lunar New Year 1969 ensure consistency with the Vietnamese calendar calculations.
283-286: Calendar date correction for Vietnamese lunar calendar.These adjustments for Lunar New Year 1985 ensure consistency with the Vietnamese calendar calculations.
484-489: Calendar date correction for Vietnamese lunar calendar.These adjustments for Lunar New Year 2007 ensure consistency with the Vietnamese calendar calculations.
511-511: Correction to Hung Kings' Commemoration Day.This adjustment from April 5 to April 4 for 2009 aligns with the PR's objective to fix calendar discrepancies for Vietnam holidays.
791-797: Calendar date correction for Vietnamese lunar calendar.These adjustments for Lunar New Year 2030 ensure consistency with the Vietnamese calendar calculations.
896-896: Calendar date correction for Vietnamese calendar.The adjustment to Hung Kings' Commemoration Day in 2037 helps maintain calendar accuracy for future dates.
909-909: Calendar date correction for Vietnamese calendar.The adjustment to Hung Kings' Commemoration Day in 2038 helps maintain calendar accuracy for future dates.
holidays/countries/vietnam.py (2)
16-17: Looks good – dedicated calendar constant keeps logic explicit.
The explicitVIETNAM_CALENDARimport clarifies intent and avoids implicit defaults.
62-68: Constructor wiring aligns correctly with new calendar API.
CallingChineseCalendarHolidays.__init__(self, calendar=VIETNAM_CALENDAR)hits the updated signature and preserves previous behaviour. No hidden side‑effects spotted.holidays/groups/chinese.py (1)
16-17: Selective import keeps public surface tidy.
Pulling only_ChineseLunisolarandCHINESE_CALENDARavoids namespace bloat.holidays/countries/south_korea.py (1)
17-18: Import is minimal and purposeful.
Keeps module dependencies lean.holidays/calendars/chinese.py (2)
1324-1331: Lookup order looks sound
exact → calendar‑override → defaultis intuitive; the verification guard prevents accidental fall‑through. Implementation matches the pattern used in other calendar modules.
1333-1349: Public helpers remain backward‑compatiblePassing
calendar=Nonekeeps the old call signature while enabling overrides—good call. No action needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Big improvements all around 🙏
I'm not really sure about Indonesia using GMT+7-based calculation though based on their historical observance in 2007.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
holidays/calendars/chinese.py (2)
1318-1322: 🧹 Nitpick (assertive)Reuse a single “supported” set to avoid drift
The error message repeats every constant manually. Building the set once (as suggested in the previous review) keeps the code DRY and prevents the typo above from happening again.
19-22: 🧹 Nitpick (assertive)Consider upgrading the calendar identifiers to an
EnumUsing an
Enum[str]gives autocomplete & type‑safety for free while remaining backwards‑compatible.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
holidays/calendars/chinese.py(9 hunks)holidays/countries/vietnam.py(2 hunks)scripts/calendar/asian_generator.py(8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
holidays/countries/vietnam.py (1)
holidays/groups/chinese.py (1)
ChineseCalendarHolidays(21-266)
🔇 Additional comments (4)
holidays/countries/vietnam.py (2)
16-17: 👍 Good catch on the constant renameImporting
VIETNAMESE_CALENDARaligns Vietnam with the new multi‑calendar mechanism.
No further action needed here.
62-64: Side‑effect of the prefix mismatchBecause the override tables in
chinese.pystill start withVIETNAM_CALENDAR_…, the line below will currently not load the Vietnamese‑specific dates:ChineseCalendarHolidays.__init__(self, calendar=VIETNAMESE_CALENDAR)Once the tables are renamed (see earlier comment), this call will behave as intended.
Until then, Vietnam will use fallback dates. Keep an eye on the fix.scripts/calendar/asian_generator.py (2)
359-362: Appreciate the explicit timezone commentsThe quick legend (UTC+7/8/9) makes the data blocks far easier to grok.
Nice touch.
246-254:✅ Verification successful
Array length vs. declared range
END_YEARis bumped to 2100, and one more element was appended toG_LUNAR_MONTH_DAYS.
A quick sanity check that the list length equalsEND_YEAR - START_YEAR + 1protects against off‑by‑one slips.shell
#!/usr/bin/env bashEnsure lunar data array length matches configured year span.
fd --extension py G_LUNAR_MONTH_DAYS -x
python - <<'PY'
import re, sys, pathlib, ast, textwrap
path = pathlib.Path("scripts/calendar/asian_generator.py")
source = path.read_text()
tree = ast.parse(source)
for node in ast.walk(tree):
if isinstance(node, ast.Assign) and any(
getattr(t, "id", None) == "G_LUNAR_MONTH_DAYS" for t in node.targets
):
count = len(node.value.elts)
start = next(n for n in ast.walk(tree)
if isinstance(n, ast.Assign) and n.targets[0].id == "START_YEAR").value.n
end = next(n for n in ast.walk(tree)
if isinstance(n, ast.Assign) and n.targets[0].id == "END_YEAR").value.n
print(f"entries={count}, span={end-start+1}")
sys.exit(0)
PYExpected output: `entries=200, span=200` --- 🏁 Script executed: ```shellLength of output: 139
🏁 Script executed:
#!/usr/bin/env bash # Show the relevant lines around the assignments sed -n '230,300p' scripts/calendar/asian_generator.py # Count G_LUNAR_MONTH_DAYS entries and compare to END_YEAR - START_YEAR + 1 python3 - <<'PY' import ast, pathlib path = pathlib.Path('scripts/calendar/asian_generator.py') src = path.read_text() tree = ast.parse(src) start = end = entries = None for node in ast.walk(tree): if isinstance(node, ast.Assign): for t in node.targets: name = getattr(t, "id", None) if name == "START_YEAR": start = node.value.n if hasattr(node.value, "n") else node.value.value elif name == "END_YEAR": end = node.value.n if hasattr(node.value, "n") else node.value.value elif name == "G_LUNAR_MONTH_DAYS": entries = len(node.value.elts) if None in (start, end, entries): print("Error: could not find START_YEAR, END_YEAR, or G_LUNAR_MONTH_DAYS") else: span = end - start + 1 print(f"entries={entries}, span={span}") PYLength of output: 2661
🏁 Script executed:
#!/usr/bin/env bash # Locate where G_LUNAR_MONTH_DAYS is defined grep -n "G_LUNAR_MONTH_DAYS" scripts/calendar/asian_generator.py # Verify START_YEAR, END_YEAR, and count of G_LUNAR_MONTH_DAYS entries python3 - <<'PY' import ast, pathlib, sys path = pathlib.Path('scripts/calendar/asian_generator.py') src = path.read_text() tree = ast.parse(src) start = end = entries = None for node in ast.walk(tree): if isinstance(node, ast.Assign): for t in node.targets: # module‐level tuple for lunar data if isinstance(t, ast.Name) and t.id == 'G_LUNAR_MONTH_DAYS': entries = len(node.value.elts) # instance attributes in __init__ if isinstance(t, ast.Attribute) and t.attr == 'START_YEAR': if isinstance(node.value, ast.Constant): start = node.value.value if isinstance(t, ast.Attribute) and t.attr == 'END_YEAR': if isinstance(node.value, ast.Constant): end = node.value.value if None in (start, end, entries): print(f"Error: could not find all values: start={start}, end={end}, entries={entries}") sys.exit(1) span = end - start + 1 print(f"entries={entries}, span={span}") PYLength of output: 449
🏁 Script executed:
#!/usr/bin/env bash # Verify that G_LUNAR_MONTH_DAYS entry count matches END_YEAR - START_YEAR + 1 python3 - <<'PY' import ast, pathlib, sys path = pathlib.Path('scripts/calendar/asian_generator.py') src = path.read_text() tree = ast.parse(src) start = end = entries = None for node in ast.walk(tree): if isinstance(node, ast.Assign): for t in node.targets: # capture the tuple literal on self.G_LUNAR_MONTH_DAYS if isinstance(t, ast.Attribute) and t.attr == 'G_LUNAR_MONTH_DAYS': if isinstance(node.value, ast.Tuple): entries = len(node.value.elts) # capture START_YEAR and END_YEAR constants if isinstance(t, ast.Attribute) and t.attr == 'START_YEAR': start = node.value.value if isinstance(node.value, ast.Constant) else None if isinstance(t, ast.Attribute) and t.attr == 'END_YEAR': end = node.value.value if isinstance(node.value, ast.Constant) else None if None in (start, end, entries): print(f"Error: could not find all values: start={start}, end={end}, entries={entries}") sys.exit(1) span = end - start + 1 print(f"entries={entries}, span={span}") PYLength of output: 33
Sanity check passed: G_LUNAR_MONTH_DAYS length matches the year span
Verified entries=200, span=200—no off‑by‑one errors detected.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🌕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great extension!
@PPsyrius thanks for review, merging this.
Proposed change
Extend Chinese Lunisolar calendar support:
Type of change
holidaysfunctionality in general)Checklist
make check, all checks and tests are green