Skip to main content

Omani Hijri Calendar - التقويم الهجري العماني - Accurate Gregorian to Omani Hijri date conversion using astronomical crescent visibility criteria

Project description

omani-hijri — التقويم الهجري العماني

مكتبة دقيقة لتحويل التاريخ الميلادي إلى التاريخ الهجري العماني باستخدام معايير الرؤية الفلكية للهلال.

Python Versions License: MIT Code style: ruff Checked with mypy

omani-hijri هي مكتبة بايثون وواجهة برمجة تطبيقات (REST API) صُممت خصيصاً لـ سلطنة عمان. على عكس محولات التاريخ الهجري القياسية التي تعتمد على تقويم أم القرى السعودي المجدول (والذي قد يختلف بمقدار يوم أو يومين في عُمان)، تستخدم هذه المكتبة المحرك الفلكي Skyfield لتقييم المعايير الفلكية الأربعة الدقيقة لرؤية الهلال والمعتمدة من قبل وزارة الأوقاف والشؤون الدينية (MARA).

المميزات

  • المحرك الفلكي: تقييم عالي الدقة لأوقات غروب الشمس، وغروب القمر، والاقتران، والاستطالة باستخدام بيانات التقويم الفلكي من وكالة ناسا (NASA JPL).
  • معايير سلطنة عمان الأربعة: حساب أطوال الأشهر بناءً على الاقتران، وعمر القمر (15 ساعة)، والاستطالة (7.5 درجات)، والمكث (20 دقيقة).
  • نظام التعديلات الرسمية: آلية مدمجة بتنسيق JSON لتصحيح التواريخ يدويًا عندما تختلف الإعلانات الرسمية للوزارة عن التوقعات الفلكية (مثلاً بسبب الغيوم). مزودة مسبقاً بالتواريخ التاريخية.
  • تحويل ثنائي الاتجاه: تحويل التاريخ الميلادي إلى هجري، والهجري إلى ميلادي.
  • الأحداث الإسلامية: الإشارة تلقائياً للتواريخ بالأحداث البارزة (العيد، رمضان، إلخ).
  • مقارنات غنية: يدعم العمليات الحسابية للتواريخ والمقارنات الغنية (<, >, ==).
  • واجهة REST API مرفقة: خادم FastAPI خلفي جاهز للاستخدام كتبعية اختيارية ([api]).

لماذا لا نستخدم hijridate؟

تطبق مكتبة hijridate الشهيرة تقويم أم القرى السعودي. ورغم كونها ممتازة، إلا أن تقويم أم القرى يُحسب بشكل مجدول وقد يختلف بمقدار يوم أو يومين عن التقويم العماني الرسمي، الذي يعتمد على معايير الرؤية الفعلية للهلال. مكتبة omani-hijri تحاكي تحديداً المعايير المستخدمة في وزارة الأوقاف والشؤون الدينية العمانية.


🚀 البدء السريع (مكتبة بايثون)

التثبيت

pip install omani-hijri

# إذا كنت ترغب أيضاً في استخدام واجهة REST API:
pip install "omani-hijri[api]"

الاستخدام الأساسي

from datetime import date, timedelta
from omani_hijri import get_omani_hijri_date, get_gregorian_date

# 1. تحويل التاريخ الميلادي إلى الهجري العماني
hijri_date = get_omani_hijri_date(date(2024, 7, 7))

print(hijri_date)
# المخرجات: 1 Muharram 1446 AH (2024-07-07)

print(f"Day: {hijri_date.day}, Month: {hijri_date.month_name_ar}")
print(f"Events: {hijri_date.to_dict()['events']}") # ['Islamic New Year']

# 2. تحويل التاريخ الهجري العماني إلى الميلادي
greg_date = get_gregorian_date(hijri_year=1446, hijri_month=9, hijri_day=1)
print(greg_date) # 2025-03-01

# 3. العمليات الحسابية والمقارنات
tomorrow = hijri_date + timedelta(days=1)
print(tomorrow > hijri_date) # True

🌐 البدء السريع (خادم FastAPI REST)

بدء تشغيل خادم API المدمج:

python run_api.py

نقاط النهاية (API Endpoints)

المسار (Endpoint) الطريقة (Method) مثال
GET /api/v1/hijri?date=YYYY-MM-DD تحويل تاريخ محدد
GET /api/v1/gregorian?year=Y&month=M&day=D تحويل التاريخ الهجري إلى ميلادي
GET /api/v1/hijri/today الحصول على تاريخ اليوم الهجري
GET /api/v1/hijri/month?year=1446&month=1 الحصول على تقويم شهر كامل
GET /api/v1/overrides عرض التعديلات الرسمية
POST /api/v1/overrides إضافة تعديل (يتطلب مفتاح API)

مثال لطلب API

curl "http://localhost:8000/api/v1/hijri?date=2024-07-06&details=true"
{
  "status": "success",
  "data": {
    "gregorian": {
      "date": "2024-07-06",
      "day": 6,
      "month": 7,
      "year": 2024,
      "day_name": "Saturday"
    },
    "hijri": {
      "date": "30-12-1445",
      "day": 30,
      "month": 12,
      "year": 1445,
      "month_name_en": "Dhul Hijjah",
      "month_name_ar": "ذو الحجة",
      "month_length": 30,
      "source": "astronomical_calculation"
    },
    "astronomical_details": {
      "moon_age_hours": 16.0,
      "elongation_degrees": 8.5,
      "lag_minutes": 42.7,
      "all_criteria_met": true
    }
  }
}

🔭 كيف تعمل المكتبة (المعايير الأربعة)

يعتمد البداية الرسمية لشهر هجري جديد في عُمان على الرؤية الفعلية للهلال. تحسب هذه المكتبة الاحتمالية الفلكية للرؤية عند غروب الشمس في مسقط في اليوم التاسع والعشرين من الشهر الحالي.

لكي يُعتبر الهلال مرئياً، يجب أن تتحقق جميع المعايير الأربعة التالية:

  1. الاقتران (Conjunction): يجب أن يحدث القمر الجديد الفلكي قبل غروب الشمس.
  2. عمر القمر (Moon Age): يجب أن يكون الوقت المنقضي من الاقتران حتى غروب الشمس ≥ 15.0 ساعة.
  3. الاستطالة (Elongation): يجب أن يكون الانفصال الزاوي بين الشمس والقمر ≥ 7.5 درجة.
  4. المكث (Lag Time): يجب أن يغيب القمر ≥ 20 دقيقة بعد غروب الشمس.

إذا تحققت جميع المعايير، ينتهي الشهر الحالي عند 29 يوماً. وإذا لم يتحقق أي منها، يكمل الشهر 30 يوماً.


🛠️ إدارة التعديلات الرسمية (Overrides)

في بعض الأحيان، حتى لو أشار الحساب الفلكي إلى أن الهلال يجب أن يكون مرئياً، فقد تمنع الظروف الجوية الغائمة اللجنة الرسمية من رؤيته. في عُمان، الإعلان الرسمي من وزارة الأوقاف هو المرجعية النهائية.

تتضمن هذه المكتبة نظام تعديلات (Overrides) للتعامل مع هذا الأمر.

متى يتم إضافة تعديل

إذا أعلنت الوزارة تاريخاً يختلف عن حساب المكتبة، يمكنك (كمطور) إضافة إدخال واحد إلى ملف overrides.json. ستبدأ المكتبة على الفور في استخدام هذا التاريخ الرسمي.

كيفية إضافة تعديل

عبر بايثون:

from datetime import date
from omani_hijri.overrides import add_override

add_override(
    hijri_year=1445,
    hijri_month=9,
    month_name_en="Ramadan",
    official_start_gregorian=date(2024, 3, 12),
    month_length=30,
    reason="Crescent not sighted due to clouds",
    source="MARA announcement"
)

عبر API:

curl -X POST "http://localhost:8000/api/v1/overrides" \
     -H "Content-Type: application/json" \
     -H "X-API-Key: your_api_key_here" \
     -d '{
           "hijri_year": 1445,
           "hijri_month": 9,
           "month_name_en": "Ramadan",
           "official_start_gregorian": "2024-03-12",
           "month_length": 30
         }'

🤝 المساهمة

المساهمات مرحب بها! إذا لاحظت أن إعلاناً رسمياً من وزارة الأوقاف يختلف عن حساب المكتبة، يرجى فتح issue أو تقديم pull request لإضافة التعديل إلى data/overrides.json.

يرجى الاطلاع على CONTRIBUTING.md لمزيد من التفاصيل.


📝 الترخيص

هذا المشروع مرخص بموجب ترخيص MIT - انظر ملف LICENSE لمزيد من التفاصيل.






omani-hijri — التقويم الهجري العماني

Accurate Gregorian to Omani Hijri date conversion using astronomical crescent visibility criteria.

Python Versions License: MIT Code style: ruff Checked with mypy

omani-hijri is a Python library and REST API specifically built for the Sultanate of Oman. Unlike standard Hijri converters that rely on the Saudi Umm al-Qura tabular calendar (which can be off by 1-2 days in Oman), this library uses the Skyfield astronomical engine to evaluate the exact four crescent visibility criteria used by the Ministry of Awqaf and Religious Affairs (MARA).

Features

  • Astronomical Engine: High-precision evaluation of sunset, moonset, conjunction, and elongation using NASA JPL ephemeris data.
  • Oman's 4 Criteria: Calculates month lengths based on Conjunction, Moon Age (15h), Elongation (7.5°), and Lag Time (20m).
  • Official Overrides System: Built-in JSON override mechanism to manually correct dates when official MARA announcements differ from astronomical predictions (e.g., due to cloud cover). Pre-seeded with historical dates.
  • Bidirectional Conversion: Convert Gregorian to Hijri and Hijri to Gregorian.
  • Islamic Events: Automatically tags dates with notable events (Eid, Ramadan, etc.).
  • Rich Comparisons: Supports datetime-like arithmetic and rich comparisons (<, >, ==).
  • REST API included: Ready-to-use FastAPI backend as an optional dependency ([api]).

Why not hijridate?

The popular hijridate library implements the Saudi Umm al-Qura calendar. While excellent, the Umm al-Qura calendar is calculated tabularly and can differ by 1-2 days from the official Omani calendar, which relies on actual physical moon sighting criteria. omani-hijri specifically models the criteria used by Oman's MARA.


🚀 Quick Start (Python Library)

Installation

pip install omani-hijri

# If you also want the REST API:
pip install "omani-hijri[api]"

Basic Usage

from datetime import date, timedelta
from omani_hijri import get_omani_hijri_date, get_gregorian_date

# 1. Convert Gregorian to Omani Hijri
hijri_date = get_omani_hijri_date(date(2024, 7, 7))

print(hijri_date)
# Output: 1 Muharram 1446 AH (2024-07-07)

print(f"Day: {hijri_date.day}, Month: {hijri_date.month_name_ar}")
print(f"Events: {hijri_date.to_dict()['events']}") # ['Islamic New Year']

# 2. Convert Omani Hijri to Gregorian
greg_date = get_gregorian_date(hijri_year=1446, hijri_month=9, hijri_day=1)
print(greg_date) # 2025-03-01

# 3. Arithmetic and Comparisons
tomorrow = hijri_date + timedelta(days=1)
print(tomorrow > hijri_date) # True

🌐 Quick Start (FastAPI REST Server)

Start the built-in API server:

python run_api.py

API Endpoints

Method Endpoint Example
GET /api/v1/hijri?date=YYYY-MM-DD Convert a specific date
GET /api/v1/gregorian?year=Y&month=M&day=D Convert Hijri to Gregorian
GET /api/v1/hijri/today Get today's Hijri date
GET /api/v1/hijri/month?year=1446&month=1 Get full month calendar
GET /api/v1/overrides List official corrections
POST /api/v1/overrides Add correction (requires API Key)

Example API Request

curl "http://localhost:8000/api/v1/hijri?date=2024-07-06&details=true"
{
  "status": "success",
  "data": {
    "gregorian": {
      "date": "2024-07-06",
      "day": 6,
      "month": 7,
      "year": 2024,
      "day_name": "Saturday"
    },
    "hijri": {
      "date": "30-12-1445",
      "day": 30,
      "month": 12,
      "year": 1445,
      "month_name_en": "Dhul Hijjah",
      "month_name_ar": "ذو الحجة",
      "month_length": 30,
      "source": "astronomical_calculation"
    },
    "astronomical_details": {
      "moon_age_hours": 16.0,
      "elongation_degrees": 8.5,
      "lag_minutes": 42.7,
      "all_criteria_met": true
    }
  }
}

🔭 How It Works (The 4 Criteria)

The official start of a new Hijri month in Oman relies on the actual sighting of the crescent moon (Hilal). This library calculates the astronomical probability of a sighting at sunset in Muscat on the 29th day of the current month.

For the moon to be considered visible, all four of the following criteria must be met:

  1. Conjunction: The astronomical new moon must have occurred before sunset.
  2. Moon Age: The time elapsed from conjunction to sunset must be ≥ 15.0 hours.
  3. Elongation: The angular separation between the Sun and Moon must be ≥ 7.5 degrees.
  4. Lag Time: The moon must set ≥ 20 minutes after the sun sets.

If all criteria pass, the current month ends at 29 days. If any fail, the month completes 30 days.


🛠️ Managing Official Overrides

Sometimes, even if the astronomical calculation says the moon should be visible, cloudy weather may prevent the official committee from seeing it. In Oman, the official announcement from MARA is the final authority.

This library includes an Override System to handle this.

When to add an override

If MARA announces a date that differs from the library's calculation, you (the developer) add one entry to the overrides.json file. The library will immediately start using this official date.

How to add an override

Via Python:

from datetime import date
from omani_hijri.overrides import add_override

add_override(
    hijri_year=1445,
    hijri_month=9,
    month_name_en="Ramadan",
    official_start_gregorian=date(2024, 3, 12),
    month_length=30,
    reason="Crescent not sighted due to clouds",
    source="MARA announcement"
)

Via API:

curl -X POST "http://localhost:8000/api/v1/overrides" \
     -H "Content-Type: application/json" \
     -H "X-API-Key: your_api_key_here" \
     -d '{
           "hijri_year": 1445,
           "hijri_month": 9,
           "month_name_en": "Ramadan",
           "official_start_gregorian": "2024-03-12",
           "month_length": 30
         }'

🤝 Contributing

Contributions are welcome! If you notice that an official MARA announcement differs from the library's calculation, please submit an issue or pull request to add the override to data/overrides.json.

Please see CONTRIBUTING.md for details.


📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

omani_hijri-0.1.0.tar.gz (34.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

omani_hijri-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file omani_hijri-0.1.0.tar.gz.

File metadata

  • Download URL: omani_hijri-0.1.0.tar.gz
  • Upload date:
  • Size: 34.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for omani_hijri-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5f188fe2e1da183811f489a1bdfac49cabf5312d5200a243f76d42bed221c53d
MD5 eda911729931aebed243fe6643adf73c
BLAKE2b-256 b3f4ffb8928cf5d4051902a26ea5e27ffd403f241789e995e7b71cf8984e791c

See more details on using hashes here.

File details

Details for the file omani_hijri-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: omani_hijri-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for omani_hijri-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 49a3817aaec537216db3c92db1c06070515336d3e26983470319c1231b06b095
MD5 d38d5dcdc502ac722e52f5997040268f
BLAKE2b-256 a0bd7e2a2fbaaa8a1527c9331f56c99307fac46a5e7b6788e07bec7fc74d87ab

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page