Skip to content

Add _IslamicMabimsLunar calendar class for MABIMS crescent visibility criteria#3603

Draft
akshiDhi wants to merge 35 commits into
vacanza:devfrom
akshiDhi:dev
Draft

Add _IslamicMabimsLunar calendar class for MABIMS crescent visibility criteria#3603
akshiDhi wants to merge 35 commits into
vacanza:devfrom
akshiDhi:dev

Conversation

@akshiDhi

@akshiDhi akshiDhi commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Proposed change

Uses skyfield to calculate moon positions at Singapore sunset
Applies MABIMS 2021 criteria (altitude >= 3°, geocentric elongation >= 6.4°)
Generates pre-computed date tables covering 1925-2052 for 7 Islamic holidays (Eid al-Fitr, Eid al-Adha, Hijri New Year, Isra and Miraj, Mawlid, Nuzul al-Quran, Ramadan Beginning)

Dates are based on Singapore's MUIS (Majlis Ugama Islam Singapura)
astronomical calculations (Hisab) as the primary reference source,
covering Eid al-Fitr and Eid al-Adha from 2001 to 2026.

Related to #2334

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

  • I've read and followed the contributing guidelines.
  • I've run make check locally; all checks and tests passed.

akshiDhi and others added 22 commits May 30, 2026 13:13
Indonesia: add 2026 Eid al-Fitr confirmed date (MAR 21)

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Philippines: add 2026 Eid al-Fitr confirmed date (MAR 20)

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Indonesia: add 2025-2026 Eid al-Adha confirmed dates

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Philippines: add 2025-2026 Eid al-Adha confirmed dates

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Removed holiday dates for 2025 and 2026 from the Philippines.

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds _IslamicMabimsLunar — a MABIMS-based Islamic calendar subclass extending _IslamicLunar, introduces confirmed-year constants and Eid/ramadan lookup/shift logic (2001–2026), exports it from the package, and adds tests validating expected and fallback behaviors.

Changes

MABIMS Islamic Calendar

Layer / File(s) Summary
Confirmed-year constants in _IslamicLunar
holidays/calendars/islamic.py
Adds EID_AL_FITR_DATES_CONFIRMED_YEARS and EID_AL_ADHA_DATES_CONFIRMED_YEARS = (2001, 2026) to _IslamicLunar.
MABIMS calendar class and visibility logic
holidays/calendars/islamic.py
Adds _IslamicMabimsLunar subclass with LATITUDE/LONGITUDE, solar/lunar position helpers, _check_mabims_criteria, and overrides for eid_al_fitr_dates, eid_al_adha_dates, and ramadan_beginning_dates that apply a one-day shift when MABIMS criteria are not met.
Calendar package export
holidays/calendars/__init__.py
Exports _IslamicMabimsLunar from the holidays.calendars package namespace.
Calendar test suite
tests/calendars/test_islamic.py
Adds TestIslamicMabimsLunar with tests for Eid al‑Fitr and Eid al‑Adha expected dates, a 2006 dual-date case, and fallback tests for years outside the confirmed range.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

test, snapshot

Suggested reviewers

  • arkid15r
  • KJhellico
  • PPsyrius
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and specifically describes the main change: adding a new _IslamicMabimsLunar calendar class implementing MABIMS crescent visibility criteria.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly relates to the changeset, detailing Islamic calendar calculations using MABIMS criteria and skyfield library integration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holidays/calendars/islamic.py`:
- Around line 4283-4339: The class currently replaces the base _IslamicLunar
EID_AL_FITR_DATES and EID_AL_ADHA_DATES with 2001–2026-only dicts, causing
out-of-range years to lose fallbacks and these entries to be treated as
estimated by _get_holiday(); instead, merge (update) these verified maps into
the base EID_AL_FITR_DATES and EID_AL_ADHA_DATES rather than overwriting them,
and ensure entries from those maps are treated as confirmed by either adding
their years to the calendar’s confirmed/custom-year handling or setting the
estimated flag to False when _get_holiday() looks up dates from those specific
dicts (reference symbols: EID_AL_FITR_DATES, EID_AL_ADHA_DATES, class
_IslamicLunar, and method _get_holiday()).

In `@tests/calendars/test_islamic.py`:
- Around line 39-44: Update the tests to assert the returned confirmation flag
from the calendar methods instead of only the date: when iterating the output of
eid_al_fitr_dates() and eid_al_adha_dates() (used in tests at the assertions
around lines testing expected_date), unpack both values (date, is_estimated) and
assert that is_estimated is False for the verified years your calendar claims to
cover, in addition to asserting the expected_date is present.
- Around line 47-57: Add the 2006 dual-date edge case to the test mapping by
updating the eid_al_adha_dates fixture in tests/calendars/test_islamic.py to
include the MABIMS case where Eid al-Adha maps to two Gregorian dates in 2006
(i.e., add a 2006 entry that contains both Gregorian date values for that year)
and ensure the test normalizes/compares tuples/lists correctly so
tuple-normalization regressions are covered for the variable eid_al_adha_dates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0fdce9cd-7af1-4870-badb-22beb3c44d89

📥 Commits

Reviewing files that changed from the base of the PR and between 0ca4bdd and 2898021.

📒 Files selected for processing (3)
  • holidays/calendars/__init__.py
  • holidays/calendars/islamic.py
  • tests/calendars/test_islamic.py

Comment thread holidays/calendars/islamic.py
Comment thread tests/calendars/test_islamic.py Outdated
Comment thread tests/calendars/test_islamic.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 3 files

Confidence score: 3/5

  • There is a concrete regression risk in holidays/calendars/islamic.py: redefining EID_AL_FITR_DATES and EID_AL_ADHA_DATES with only 2001–2026 values appears to replace the base _IslamicLunar tables, which can remove Eid dates for years outside that range.
  • Because this is a user-visible holiday-calculation behavior change (severity 6/10, confidence 7/10), the PR carries some merge risk rather than being a low-risk cleanup.
  • If this override is intentional, consider merging with a fallback/merge strategy so base-year coverage is preserved and existing behavior does not regress.
  • Pay close attention to holidays/calendars/islamic.py - date table overrides may truncate supported years and break Eid results outside 2001–2026.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread holidays/calendars/islamic.py Outdated
@KJhellico

Copy link
Copy Markdown
Collaborator

@akshiDhi, #2334 is to implement the calculation of the start dates of Islamic months according to MABIMS criteria, not just to take the dates of two holidays within a narrow range of years.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/calendars/test_islamic.py`:
- Around line 67-75: The test test_fallback_to_base_outside_range currently
asserts is_estimated for entries from dates_1990 but omits checking dates_2030;
update the test to assert that all entries from both
self.calendar.eid_al_fitr_dates(1990) and self.calendar.eid_al_fitr_dates(2030)
have is_estimated True (e.g., iterate over both lists or concatenate them and
assert is_estimated for each tuple), keeping existing length checks and the test
name the same.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 161a778e-59ef-408d-863e-768bf91d6bfc

📥 Commits

Reviewing files that changed from the base of the PR and between 2898021 and b61f1b7.

📒 Files selected for processing (2)
  • holidays/calendars/islamic.py
  • tests/calendars/test_islamic.py

Comment thread tests/calendars/test_islamic.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
holidays/calendars/islamic.py (1)

1001-1002: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

These confirmed-year ranges are not wired into _get_holiday().

Lines 1001-1002 add plain EID_*_DATES_CONFIRMED_YEARS, but _get_holiday() only reads the postfixed ..._DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX} attribute on Lines 4147-4150. As written, super().eid_al_fitr_dates(year) / super().eid_al_adha_dates(year) still yield is_estimated=True, so the MABIMS overrides keep returning estimated dates inside 2001-2026.

Suggested fix
-        confirmed_years = _normalize_tuple(
-            getattr(
-                self, f"{holiday}_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", ()
-            )
-        )
+        confirmed_years = _normalize_tuple(
+            getattr(
+                self,
+                f"{holiday}_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}",
+                getattr(self, f"{holiday}_DATES_CONFIRMED_YEARS", ()),
+            )
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/calendars/islamic.py` around lines 1001 - 1002, The new constants
EID_AL_FITR_DATES_CONFIRMED_YEARS and EID_AL_ADHA_DATES_CONFIRMED_YEARS aren't
being used by _get_holiday() because that function only looks for attributes
suffixed with _CustomCalendar.CUSTOM_ATTR_POSTFIX; update the code to either set
the confirmed-year values under the expected attribute names (e.g., create
EID_AL_FITR_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX} and
EID_AL_ADHA_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}) or
change _get_holiday() to fallback to the plain constants when the postfixed
versions are missing, and ensure that calls to super().eid_al_fitr_dates(year)
and super().eid_al_adha_dates(year) will see is_estimated=False for years in the
confirmed ranges.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holidays/calendars/islamic.py`:
- Around line 4306-4326: _check_mabims_criteria currently uses a
declination-difference heuristic and ignores LONGITUDE, so replace it with a
proper topocentric altitude check at local sunset: use
_get_solar_lunar_positions to obtain geocentric RA/Dec (or ecliptic long/lat
converted to RA/Dec), compute local sidereal time from days_since_j2000 and
self.LONGITUDE, derive the moon's local hour angle and then convert RA/Dec +
observer lat (self.LATITUDE) to topocentric altitude; compute the sunset time by
solving for the Sun's hour angle at altitude ≈ -0.833° (or use an existing
sunset routine) and evaluate the moon altitude at that sunset time, then apply
the MABIMS thresholds (e.g., altitude >= 3.0° and elongation >= 6.4°).
Alternatively, if you cannot implement a validated topocentric sunset,
remove/disable algorithmic checks in _check_mabims_criteria and use explicit
trusted dates in _CustomIslamicHolidays / CONFIRMED_YEARS instead.
- Around line 4286-4324: The module is missing the math import causing NameError
when calling _get_solar_lunar_positions or _check_mabims_criteria; add "import
math" at the top of the module (near other imports) so all uses of math.sin,
math.cos, math.radians, math.degrees, math.acos, math.asin, etc. in
_get_solar_lunar_positions and _check_mabims_criteria resolve correctly.

---

Duplicate comments:
In `@holidays/calendars/islamic.py`:
- Around line 1001-1002: The new constants EID_AL_FITR_DATES_CONFIRMED_YEARS and
EID_AL_ADHA_DATES_CONFIRMED_YEARS aren't being used by _get_holiday() because
that function only looks for attributes suffixed with
_CustomCalendar.CUSTOM_ATTR_POSTFIX; update the code to either set the
confirmed-year values under the expected attribute names (e.g., create
EID_AL_FITR_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX} and
EID_AL_ADHA_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}) or
change _get_holiday() to fallback to the plain constants when the postfixed
versions are missing, and ensure that calls to super().eid_al_fitr_dates(year)
and super().eid_al_adha_dates(year) will see is_estimated=False for years in the
confirmed ranges.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fd71cd61-e1f4-4052-a151-da5cb8198bf9

📥 Commits

Reviewing files that changed from the base of the PR and between b61f1b7 and 0181e76.

📒 Files selected for processing (1)
  • holidays/calendars/islamic.py

Comment thread holidays/calendars/islamic.py Outdated
Comment thread holidays/calendars/islamic.py Outdated
@sonarqubecloud

sonarqubecloud Bot commented Jun 4, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
holidays/calendars/islamic.py (1)

1001-1002: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the confirmed-year ranges on the MABIMS subclass, not the shared base.

_get_holiday() reads EID_*_DATES_CONFIRMED_YEARS from self, so putting (2001, 2026) on _IslamicLunar flips the estimated flag for every generic Islamic-calendar consumer in that range. That suppresses downstream "estimated" labels well outside this feature. Move these ranges to _IslamicMabimsLunar (or keep explicit confirmed dates there) so only the MABIMS calendar claims those years are confirmed.

Suggested direction
 class _IslamicLunar:
-    EID_AL_FITR_DATES_CONFIRMED_YEARS = (2001, 2026)
-    EID_AL_ADHA_DATES_CONFIRMED_YEARS = (2001, 2026)
-
 class _IslamicMabimsLunar(_IslamicLunar):
+    EID_AL_FITR_DATES_CONFIRMED_YEARS = (2001, 2026)
+    EID_AL_ADHA_DATES_CONFIRMED_YEARS = (2001, 2026)

Based on learnings: CONFIRMED_YEARS represents years where the underlying calculation has actually been verified, and Islamic holiday dates should only be treated as confirmed when officially verified.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/calendars/islamic.py` around lines 1001 - 1002, The confirmed-year
tuples EID_AL_FITR_DATES_CONFIRMED_YEARS and EID_AL_ADHA_DATES_CONFIRMED_YEARS
should not live on the shared _IslamicLunar base because _get_holiday() reads
them from self and that causes non‑MABIMS calendars to be treated as "confirmed"
for 2001–2026; move those constants (or their explicit confirmed-date lists)
into the MABIMS-specific subclass _IslamicMabimsLunar so only
_IslamicMabimsLunar reports those years as confirmed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@holidays/calendars/islamic.py`:
- Around line 1001-1002: The confirmed-year tuples
EID_AL_FITR_DATES_CONFIRMED_YEARS and EID_AL_ADHA_DATES_CONFIRMED_YEARS should
not live on the shared _IslamicLunar base because _get_holiday() reads them from
self and that causes non‑MABIMS calendars to be treated as "confirmed" for
2001–2026; move those constants (or their explicit confirmed-date lists) into
the MABIMS-specific subclass _IslamicMabimsLunar so only _IslamicMabimsLunar
reports those years as confirmed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7c138b08-8927-42a6-a1a9-1e01c7c7205f

📥 Commits

Reviewing files that changed from the base of the PR and between ac8dfc7 and 4c15261.

📒 Files selected for processing (2)
  • holidays/calendars/islamic.py
  • tests/calendars/test_islamic.py

Comment thread holidays/calendars/islamic.py Outdated
@akshiDhi

akshiDhi commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

i updated the implementation following the feedback.

Comment on lines +48 to +51
# Singapore coordinates (primary MABIMS Hisab reference).
SINGAPORE_LAT = 1.3521
SINGAPORE_LON = 103.8198
SINGAPORE_ELEV = 15.0 # meters

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is Singapore used as the reference location? Please provide the source that defines it as the MABIMS reference point.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

in issue #2334 ppsyrius mentions singapore as reference location and it is the only MABIMS member that relies exclusively on Hisāb (astronomical calculation) since 1974 making it a consistent reference for this issue and other MAIBMS members use Ru'yah which depends on human sightings and weather as their final determinantion method. Singapore's calculation gives the MABIMS result that all member countries typically follow.
Source :
https://www.muslim.sg/articles/ramadan-countdown-unity-in-diversity
https://www.muis.gov.sg/resources/media-releases/announcement-by-mufti-for-the-month-of-syawal-1446h--2025--for-singapore

Comment thread scripts/calendar/mabims_generator.py Outdated

def check_mabims_visibility(ts, eph, observer, check_date: date) -> bool:
"""Check if crescent moon meets MABIMS criteria at Singapore sunset."""
t = ts.utc(check_date.year, check_date.month, check_date.day, 11, 0, 0) # ~sunset UTC+8

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not the exact sunset time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah i fixed it. Now it uses almanac.sunrise_sunset() from skyfield to calculate the exact sunset time for Singapore. Falls back to approximate time only if sunset cannot be found in the expected window

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review.

@KJhellico

Copy link
Copy Markdown
Collaborator

General advice on the algorithm:

  • use new moon moments instead of HijriDate-calculated dates for reference points
  • implement the methods in a separate class, as in other generators (this will allow to avoid passing unnecessary parameters)

akshiDhi added 5 commits June 19, 2026 18:53
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Added type annotations for various date attributes in the _IslamicLunar class.

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Removed unused import of the math module.

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
Signed-off-by: akshiDhi <jamkim2224@gmail.com>
…ations

Signed-off-by: akshiDhi <jamkim2224@gmail.com>
@akshiDhi

akshiDhi commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

I have updated the PR based on your feedback:

  • Refactored mabims_generator.py into a separate class (_MabimsLunar) to encapsulate the calculations.
  • Replaced the hijridate approximation with direct astronomical new moon calculations using MEAN_SYNODIC_MONTH and Skyfield.

@KJhellico

Copy link
Copy Markdown
Collaborator
  • direct astronomical new moon calculations using MEAN_SYNODIC_MONTH and Skyfield

If you're already using Skyfield, you should take advantage of its features, including calculating arrays of values all at once, rather than one by one. I mean something like

    times, events = almanac.find_discrete(t0, t1, almanac.moon_phases(eph))
    new_moons = [
        moment for moment, phase in zip(times, events) if phase == 0
    ]

for the entire timeframe.

@akshiDhi

akshiDhi commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

thank you ! I updated the script to take advantage of Skyfield's vector arrays. (i chunked the find_discrete() calls year-by-year in a loop to avoid a Skyfield memory error)

Comment thread scripts/calendar/mabims_generator.py Outdated
Comment on lines +89 to +97
def get_approximate_date(self, h_year: int, h_month: int) -> date:
months_since_epoch = (h_year - 1) * 12 + (h_month - 1)
approx_days = int(months_since_epoch * MEAN_SYNODIC_MONTH)
return HIJRI_EPOCH + timedelta(days=approx_days)

def get_new_moon_date(self, approximate_date: date) -> date:
"""Find the closest precalculated new moon (conjunction) near the given date."""
# Find the new moon with the minimum absolute difference in days
return min(self.new_moons, key=lambda nm: abs((nm - approximate_date).days))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's the point of all this? You can just cycle through the calculated new moon moments.

@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/calendar/mabims_generator.py">

<violation number="1" location="scripts/calendar/mabims_generator.py:110">
P2: `get_new_moon_date` directly indexes `self.new_moons` without checking that the computed index is within the precomputed list. If the generation range is ever extended to earlier Hijri years, Python's negative list indexing will silently return an unrelated new-moon date from the end of the table, corrupting the generated calendar data. Adding an explicit bounds check (or an `assert`) would make the script resilient to range changes and prevent silent failures.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

def get_new_moon_date(self, h_year: int, h_month: int) -> date:
"""Get the exact precalculated new moon (conjunction) for a given Hijri month."""
months_since_epoch = (h_year - 1) * 12 + (h_month - 1)
return self.new_moons[months_since_epoch - self.month_offset]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: get_new_moon_date directly indexes self.new_moons without checking that the computed index is within the precomputed list. If the generation range is ever extended to earlier Hijri years, Python's negative list indexing will silently return an unrelated new-moon date from the end of the table, corrupting the generated calendar data. Adding an explicit bounds check (or an assert) would make the script resilient to range changes and prevent silent failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/calendar/mabims_generator.py, line 110:

<comment>`get_new_moon_date` directly indexes `self.new_moons` without checking that the computed index is within the precomputed list. If the generation range is ever extended to earlier Hijri years, Python's negative list indexing will silently return an unrelated new-moon date from the end of the table, corrupting the generated calendar data. Adding an explicit bounds check (or an `assert`) would make the script resilient to range changes and prevent silent failures.</comment>

<file context>
@@ -85,24 +90,30 @@ def __init__(self) -> None:
+    def get_new_moon_date(self, h_year: int, h_month: int) -> date:
+        """Get the exact precalculated new moon (conjunction) for a given Hijri month."""
+        months_since_epoch = (h_year - 1) * 12 + (h_month - 1)
+        return self.new_moons[months_since_epoch - self.month_offset]
 
     def check_mabims_visibility(self, check_date: date) -> bool:
</file context>
Suggested change
return self.new_moons[months_since_epoch - self.month_offset]
idx = months_since_epoch - self.month_offset
if not 0 <= idx < len(self.new_moons):
raise ValueError(
f"Hijri month ({h_year}-{h_month}) is outside the precomputed new-moon range."
)
return self.new_moons[idx]

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.

2 participants