Metadata-Version: 2.4
Name: jamshid
Version: 0.3.1
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: matplotlib>=3.0 ; extra == 'matplotlib'
Requires-Dist: pandas>=1.0 ; extra == 'pandas'
Provides-Extra: matplotlib
Provides-Extra: pandas
Summary: A highly accurate and modern Persian (Jalali) calendar library written in Rust and Python.
Author-email: Ali Kamrani <kamrani.exe@gmail.com>
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/MRThugh/Jamshid

<div align="center">

# 🌟 Jamshid (جمشید) 🌟
<p align="center">
  <img 
    src="https://raw.githubusercontent.com/MRThugh/MRThugh/main/badge.svg"
    width="50%" 
  />
</p>

[![Python Version](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
[![Rust Engine](https://img.shields.io/badge/engine-Rust--PyO3-orange.svg)](https://www.rust-lang.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![Author](https://img.shields.io/badge/author-Ali%20Kamrani-purple.svg)](https://github.com/MRThugh)
[![Version](https://img.shields.io/badge/version-0.3.0-blue.svg)](https://github.com/MRThugh/Jamshid)
[![Persian](https://img.shields.io/badge/lang-PERSIAN-green)](README-fa.md)
[![English](https://img.shields.io/badge/lang-English-blue)](README.md)

**The definitive, ultra-performant Persian (Jalali) calendar infrastructure for Python. Powered by a lightning-fast Rust core, featuring native Pandas integration, multi-regional holiday engines, and rich cultural diagnostics.**

</div>

---

## 📖 Overview

**Jamshid** (imported as `jamshid`) is a production-grade, highly performant calendar library designed as a full-scale infrastructure for Jalali-Gregorian date processing in Python. 

By combining the speed and type safety of **Rust (via PyO3)** with Python's standard `datetime` interfaces, Jamshid offers microsecond-level performance while remaining a drop-in replacement for standard calendar structures. 

Whether you are building astronomical utilities, high-frequency financial platforms using **Pandas**, or localized web services, Jamshid provides the mathematical precision, localized text processors, and cultural database required for modern Persian software engineering.

---

## 🚀 Key Architectural Pillars in v0.3.0

### 1. High-Performance Rust Core (`jamshid._core`)
* **Compiled Mathematical Operations**: Transformation algorithms (Jalali ↔ Gregorian), day-of-the-week determination, and leap-year verifications are processed entirely in natively compiled Rust binaries.
* **Astronomical Accuracy**: Supports the highly accurate Borkowski 2820-year cycle algorithm alongside Jean Meeus astronomical formulas for approximating the vernal equinox, guaranteeing mathematical continuity from year `-3000` to `3000`.

### 2. Multi-Regional Cultural Engine (`jamshid.core`)
* **Multi-Country Support**: Out-of-the-box holiday calendars for **Iran**, **Afghanistan**, and **Tajikistan** (customizable via region flags).
* **Categorized Events Database**: Appropriate classification of events into `official`, `cultural`, `historical`, and `religious` categories, drawing from both solar and lunar calendars (with tabular fallback systems for distant years).

### 3. Native Data Science Toolchain (`jamshid.pandas_ext`)
* **JalaliIndex**: A custom Pandas index subclassing the standard Pandas Index layer, permitting native slice filtering, year/month/day properties, and flawless conversions.
* **Custom Frequency Offsets**: Native date offsets like `JalaliMonthEnd` (JME) and `JalaliYearEnd` (JYE) to streamline Jalali-based financial and accounting resamples.

### 4. Advanced Persian Linguistic Diagnostics
* **Iterative Digit Converters**: Ultra-fast bidirectional converters supporting Persian, English, and Arabic digit scripts.
* **Iterative Num-To-Words**: A highly optimized, non-recursive, memory-safe algorithm converting numbers up to Quadrillions into Persian text representation.
* **Text Normalizer**: Clean Persian script layouts, fixing non-breaking spaces, semi-spaces (ZWNJs), and Arabic glyph issues.

---

## ⚙️ Installation

### 1. Standard Installation
```bash
pip install jamshid
```

### 2. Install with Scientific Extras (Pandas & Plotting)
```bash
pip install jamshid[pandas,matplotlib]
```

### 3. Compilation from Source
For custom optimizations or local contributions, compile directly using `maturin`:
```bash
git clone https://github.com/MRThugh/Jamshid.git
cd Jamshid
pip install maturin setuptools-rust
maturin develop --extras pandas,matplotlib
```

*Requires Python 3.9+ and Rust compiler (M.S.R.V 1.65+).*

---

## 🛠️ Global Configuration & Exceptions

Jamshid provides robust validation pipelines and descriptive, dual-language exception triggers to ensure validation issues are caught early in the development lifecycle.

```python
import jamshid

# Custom exceptions tailored for Clean Architecture
try:
    # 1404 is not a leap year, so Esfand has 29 days
    invalid_date = jamshid.JalaliDate(1404, 12, 30)
except jamshid.JalaliRangeError as e:
    print(f"Validation failed: {e}")
    # Output: Validation failed: روز 30 برای ماه 12 در سال 1404 (غیرکبیسه) نامعتبر است.
    #         [Day 30 is invalid for month 12 in year 1404 (غیرکبیسه). Max allowed days: 29].
```

---

## 🚀 Quick Start Examples

```python
from jamshid import JalaliDate, JalaliDateTime, TehranTz
import datetime

# 1. Base Instantiation & Standard Compatibility
d = JalaliDate(1405, 4, 14)  # 1405/04/14
dt = JalaliDateTime.now(TehranTz())

# 2. Seamless Gregorian Conversion
g_date = d.to_gregorian()    # Returns standard datetime.date(2026, 7, 5)
jd = JalaliDate.from_date(g_date)

# 3. Simple Spacing Arithmetic
tomorrow = d + datetime.timedelta(days=1)
days_between = JalaliDate(1405, 4, 20) - d  # Returns datetime.timedelta(days=6)

# 4. Humanized Interval Text
birth_date = JalaliDate(1375, 6, 15)
print(birth_date.humanize())  # Output: ۲۹ سال پیش (approx relative to 2026)

# 5. Fast Digit conversion & Formatting
print(d.strftime("امروز %A، %d %B سال %Y", locale='fa'))
# Output: امروز یک‌شنبه، ۱۴ تیر سال ۱۴۰۵
```

---

## 📖 Deep API Reference

### 1. `JalaliDate` & `JalaliDateTime`
Inheriting directly from `datetime.date` and `datetime.datetime` respectively, these classes act as drop-in replacements with overridden date properties.

```python
from jamshid import JalaliDate, JalaliDateTime

# Static validation checking
is_ok = JalaliDate.is_valid(1404, 12, 30)  # False

# RTL formatting support (Prevents crooked outputs in mixed LTR/RTL terminals)
d = JalaliDate(1405, 4, 14)
print(repr(d.strftime_rtl("%Y/%m/%d")))  # Includes \u200f right-to-left marks

# Exact Moon Phase Calculations
phase_name, illumination = d.get_moon_phase()
print(f"Moon Phase: {phase_name} | Illumination: {illumination:.2f}%")
# Output: Moon Phase: هلال کاهنده (Waning Crescent) | Illumination: 78.43%
```

### 2. Timezones & Tehran Historical DST (`TehranTz`)
The official Iranian Daylight Saving Time (DST) was legally abolished from 1402 خورشیدی (2023 CE). Jamshid's `TehranTz` implements correct historical DST offsets (24:00 of 1 Farvardin to 24:00 of 30 Shahrivar) up to 1401 and shuts off DST dynamically starting from 1402.

```python
from jamshid import JalaliDateTime, TehranTz

tz = TehranTz()
# Before 1402 (DST Applied)
dt_1400 = JalaliDateTime(1400, 2, 15, 12, 0, tzinfo=tz)
print(dt_1400.tzname())  # IRDT (+04:30)

# After 1402 (DST Abolished)
dt_1405 = JalaliDateTime(1405, 2, 15, 12, 0, tzinfo=tz)
print(dt_1405.tzname())  # IRST (+03:30)
```

### 3. Highly Advanced Age Inquiries (`SolarAge`)
Computes astronomical age based on actual orbital movement, providing the result in days, months, years, exact fraction decimals, and formatted Persian text.

```python
from jamshid import JalaliDate

birth = JalaliDate(1375, 6, 15)
ref_date = JalaliDate(1405, 4, 14)

age = birth.age_to(ref_date)
print(age.years, "Years,", age.months, "Months,", age.days, "Days")
# Output: 29 Years, 9 Months, 29 Days

print(f"Decimal Solar Age: {age.fraction:.4f}")
# Output: Decimal Solar Age: 29.8282

print(age.to_persian())
# Output: ۲۹ سال و ۹ ماه و ۲۹ روز
```

### 4. Continuous Date Interval Containers (`JalaliPeriod`)
```python
from jamshid import JalaliDate, JalaliPeriod

start = JalaliDate(1405, 1, 1)
end = JalaliDate(1405, 1, 31)
period = JalaliPeriod(start, end)

print(JalaliDate(1405, 1, 15) in period)  # True
print(period.days)  # 30
```

### 5. Persian Linguistic Utilities
```python
import jamshid.core as j_utils

# Bidirectional Converters
print(j_utils.to_persian_digits("Calling 09123456789"))  # Calling ۰۹۱۲۳۴۵۶۷۸۹
print(j_utils.to_english_digits("تلفن: ۰۹۱۲۳۴۵۶۷۸۹"))      # تلفن: 09123456789

# Non-Recursive Number-To-Words (Capable of handling huge integers)
print(j_utils.num_to_words(1405623910))
# Output: یک میلیارد و چهارصد و پنج میلیون و ششصد و بیست و سه هزار و نهصد و ده

# Standardize Mixed Spacing & Unicode Glyphs
dirty = "كتاب‌ ها  ميباشد‌"
print(j_utils.normalize_persian(dirty))  # کتاب‌ها میباشد
```

---

## 📈 Pandas & Data Science Suite

Jamshid provides robust structures to carry out analytics, resamples, and aggregations using Jalali dates natively inside **Pandas**.

```python
import pandas as pd
import jamshid
from jamshid.pandas_ext import JalaliIndex, jalali_date_range, JalaliMonthEnd, JalaliYearEnd

# 1. Generate an regular Jalali Index range
idx = jalali_date_range(start="1405/01/01", end="1405/03/31", freq="D")
print(idx)
# Output: JalaliIndex([1405/01/01, 1405/01/02, ..., 1405/03/31], dtype='object')

# Extract custom properties
print(idx.year)   # pd.Index([1405, 1405, ...])
print(idx.month)  # pd.Index([1, 1, 1, ...])

# 2. DataFrame Integration & Series Accessor
df = pd.DataFrame({
    "g_date": pd.date_range("2026-03-21", "2026-06-21", freq="D")
})

# Convert Gregorian column to JalaliDate objects using accessor
df["j_date"] = df["g_date"].jalali.to_jalali()

# Map properties directly through Series Accessor
df["is_holiday"] = df["j_date"].jalali.is_holiday
df["daily_events"] = df["j_date"].jalali.events

# 3. Monthly Financial Resampling using Jalali Month End (JME) offsets
df_financial = pd.DataFrame({"revenue": [1000, 1500, 2000]}, index=idx[:3])
# Resample on custom monthly boundaries
monthly_resampled = df_financial.resample(JalaliMonthEnd()).sum()
```

---

## 🖼️ Graphical Visualization (`plot_calendar`)
For reporting, UI rendering, or data notebooks, plot localized monthly calendars in high definition with a single call:

```python
from jamshid import JalaliDate

# Select any day inside the target month
d = JalaliDate(1405, 4, 14)
# Plots Farvardin 1405 grid with today highlighted
fig = d.plot_calendar()
fig.savefig("calendar_july_2026.png")
```

---

## 💻 Professional CLI Reference

Jamshid comes equipped with a comprehensive terminal user interface featuring ANSI colors, export options, and localized reporting.

### 1. Show Today's Detailed Diagnostics
```bash
jamshid today
```
*Outputs current Jalali date, Gregorian representation, localized week name, time, and active holidays.*

### 2. Calculate Complex Date Differences
```bash
jamshid diff 1405/01/01 1406/05/12 --human
```
*Prints: `Difference: ۱ سال و ۵ ماه و ۱۱ روز بعد`*

### 3. Display Terminal Calendar Grids with Holiday Highlighting
```bash
jamshid calendar 1405 --highlight-holidays
```
*Outputs the complete grid of 1405 with holidays colored in red.*

### 4. Fetch Public Holidays & Export to Standards (JSON, CSV, iCal)
```bash
# Export official holidays to iCal format for Google Calendar/Outlook import
jamshid holidays 1405 --filter official --export ical > holidays_1405.ics

# Export to JSON
jamshid holidays 1405 --filter cultural --export json
```

---

## 📊 Feature Comparison Matrix

| Feature | **Jamshid (v0.3.0)** | `jdatetime` | `persiantools` | `khayyam` |
| :--- | :---: | :---: | :---: | :---: |
| **Engine Language** | **Rust (compiled PyO3)** | Pure Python | Pure Python | Pure Python |
| **Performance** | **Ultra-Fast (Microseconds)** | Baseline | Baseline | Moderate |
| **Pandas Support** | **Full (JalaliIndex + Offsets)** | ❌ None | ❌ None | ❌ None |
| **Historical Precision** | **Borkowski 2820-yr cycle** | Arithmetic 33-yr cycle | Basic Cycle | Arithmetic |
| **Year Range Support** | **-3000 to 3000** | 1 to 9999 | 1 to 9999 | 1 to 9999 |
| **Tehran DST Historical** | **Active (Auto-abolished 1402)**| Constant Offset | ❌ None | Constant Offset |
| **Multi-Region Holidays** | **Iran, Afghanistan, Tajikistan**| ❌ None | ❌ None | ❌ None |
| **Graphical Plotting** | **Matplotlib Integration** | ❌ None | ❌ None | ❌ None |
| **Linguistic Utilities** | **Words, Digits, Normalize** | ❌ None | Moderate | ❌ None |
| **Interactive CLI** | **Comprehensive JSON/ICS** | ❌ None | ❌ None | ❌ None |

---

## 🧪 Technical Benchmarks & Performance
Due to calculations being processed natively on the Rust stack, conversions, indexing, and arithmetic steps in Jamshid achieve massive throughput improvements compared to traditional pure-Python solutions:

```python
# Simple Benchmark comparison test (Converting 100,000 Dates)
import time
import jdatetime
import jamshid

# jdatetime baseline
t0 = time.time()
for _ in range(100000):
    _ = jdatetime.date.fromgregorian(day=5, month=7, year=2026)
print(f"jdatetime: {time.time() - t0:.4f} seconds")

# Jamshid (Rust PyO3 engine)
t0 = time.time()
for _ in range(100000):
    _ = jamshid.JalaliDate.from_gregorian(2026, 7, 5)
print(f"Jamshid: {time.time() - t0:.4f} seconds")
```
*On modern benchmark hardware, Jamshid operates **4x to 8x** faster during batch transformations, making it the premier choice for large-scale databases and data analysis.*

---

## 🤝 Contributing

Contributions to Jamshid are highly welcome!
1. Fork the Project.
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`).
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`).
4. Push to the Branch (`git push origin feature/AmazingFeature`).
5. Open a Pull Request.

Make sure to run the unit tests prior to opening requests:
```bash
python -m unittest discover -s tests
```

---

## 👨‍💻 Author & Contact

**Ali Kamrani**

* **GitHub**: [@MRThugh](https://github.com/MRThugh)
* **Email**: [kamrani.exe@gmail.com](mailto:kamrani.exe@gmail.com)

---

## 📄 License

This software infrastructure is distributed under the **MIT License**. Feel free to use, adapt, and build upon it in commercial and open-source applications alike.

---

<div align="center">
  <b>Jamshid</b> — Redefining Persian Calendar Computing. 🚀
</div>
