Jalali Pandas Extension
Full-featured Jalali (Persian/Shamsi) calendar support for pandas — A complete pandas extension providing native Jalali datetime types, time series operations, and calendar-aware functionality.
✨ Features
🎯 Core Types
- JalaliTimestamp: Full-featured scalar type with all date/time properties
- JalaliDatetimeDtype: Registered pandas extension dtype (
jalali_datetime64[ns]) - JalaliDatetimeArray: Extension array for Series storage with vectorized operations
- JalaliDatetimeIndex: Complete pandas Index implementation with Jalali awareness
📅 Date Range & Conversion
- jalali_date_range(): Generate date ranges with frequency support (daily, monthly, quarterly, yearly)
- to_jalali_datetime() / to_gregorian_datetime(): Bidirectional conversion for all input types
- String parsing with multiple formats:
"1402-06-15","1402/6/15","1402-06","1402"
🔄 Frequency Offsets
- JalaliMonthEnd/Begin: Handle Jalali month boundaries (31-day months 1-6, 30-day months 7-11, Esfand 29/30)
- JalaliQuarterEnd/Begin: Quarter boundaries respecting Jalali calendar
- JalaliYearEnd/Begin: Year boundaries (1 Farvardin start, 29/30 Esfand end)
- JalaliWeek: Saturday-based weeks with custom weekday support
- Frequency aliases:
JME,JMS,JQE,JQS,JYE,JYS,JW
📊 Time Series Operations
- resample_jalali(): Jalali-aware resampling with proper calendar boundaries
- JalaliGrouper: Calendar-based grouping by year/month/quarter/day
- Enhanced Accessors: Full Series and DataFrame accessor support
- Properties:
year,month,day,quarter,week,weekday,is_leap_year, etc. - Methods:
strftime(),normalize(),floor(),ceil(),round(),tz_localize(),tz_convert()
- Properties:
🧪 Quality & Performance
- 94% test coverage with 563+ passing tests
- Type hints throughout (PEP 561 compliant)
- Python 3.9-3.13 support
- pandas 2.0-2.2 compatibility
📦 Installation
Using pip
pip install jalali-pandas
For development:
pip install jalali-pandas[dev]
Using uv (recommended for faster installation)
uv add jalali-pandas
For development:
uv add --dev jalali-pandas
🚀 Quick Start
Basic Usage
import pandas as pd
import jalali_pandas
from jalali_pandas import jalali_date_range, to_jalali_datetime
# Create a Jalali date range
jdates = jalali_date_range("1402-01-01", periods=10, freq="D")
print(jdates)
# JalaliDatetimeIndex(['1402-01-01', '1402-01-02', ..., '1402-01-10'], dtype='jalali_datetime64[ns]', freq='D')
# Convert Gregorian to Jalali
gregorian_dates = pd.date_range("2023-01-01", periods=5)
jalali_dates = to_jalali_datetime(gregorian_dates)
print(jalali_dates)
# JalaliDatetimeIndex(['1401-10-11', '1401-10-12', ..., '1401-10-15'], dtype='jalali_datetime64[ns]')
Series Operations
import pandas as pd
import jalali_pandas
# Create a DataFrame with Gregorian dates
df = pd.DataFrame({
"date": pd.date_range("2023-01-01", periods=10, freq="D"),
"value": range(10)
})
# Convert to Jalali using accessor
df["jdate"] = df["date"].jalali.to_jalali()
# Access Jalali date components
df["year"] = df["jdate"].jalali.year
df["month"] = df["jdate"].jalali.month
df["day"] = df["jdate"].jalali.day
df["quarter"] = df["jdate"].jalali.quarter
df["weekday"] = df["jdate"].jalali.weekday
df["is_leap"] = df["jdate"].jalali.is_leap_year
# Format as Persian strings
df["persian_date"] = df["jdate"].jalali.strftime("%Y/%m/%d")
DataFrame Operations
import pandas as pd
import jalali_pandas
from jalali_pandas import jalali_date_range
# Create DataFrame with Jalali dates
df = pd.DataFrame({
"date": jalali_date_range("1402-01-01", periods=100, freq="D"),
"value": range(100)
})
# Group by Jalali year and month
monthly = df.jalali.groupby(["year", "month"]).sum()
# Use shortcuts for common groupings
yearly = df.jalali.groupby("year").mean() # Group by year
quarterly = df.jalali.groupby("yq").sum() # Group by year-quarter
daily = df.jalali.groupby("ymd").count() # Group by year-month-day
# Resample with Jalali calendar awareness
monthly_resample = df.set_index("date").resample_jalali("JME").sum()
quarterly_resample = df.set_index("date").resample_jalali("JQE").mean()
Advanced Features
from jalali_pandas import JalaliTimestamp
from jalali_pandas.offsets import JalaliMonthEnd, JalaliYearEnd
# Create Jalali timestamps
jts = JalaliTimestamp(1402, 6, 15, 12, 30, 0)
print(jts.strftime("%Y/%m/%d %H:%M")) # 1402/06/15 12:30
# Use frequency offsets
end_of_month = jts + JalaliMonthEnd()
end_of_year = jts + JalaliYearEnd()
# Timezone support
jts_tehran = jts.tz_localize("Asia/Tehran")
jts_utc = jts_tehran.tz_convert("UTC")
📚 Documentation
- Full Documentation: https://ghodsizadeh.github.io/jalali-pandas/
- API Reference: https://ghodsizadeh.github.io/jalali-pandas/en/api/
- Examples: 11 Python examples + 2 Jupyter notebooks
- Persian Documentation: مستندات فارسی
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
📝 License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
🙏 Acknowledgments
- Built on top of pandas and jdatetime
- Inspired by the need for proper Jalali calendar support in data analysis
راهنمای فارسی
برای مطالعه راهنمای فارسی استفاده از کتابخانه به این آدرس مراجعه کنید:
- مستندات کامل: https://ghodsizadeh.github.io/jalali-pandas/fa/
- راهنمای نصب: نصب و راهاندازی
- آموزش سریع: شروع سریع
- مقاله آموزشی: معرفی بسته pandas-jalali | آموزش کار با تاریخ شمسی در pandas
راهنمای ویدیویی
Metadata
Release files for jalali-pandas 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jalali_pandas-1.0.0.tar.gz | 101.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jalali_pandas-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 179.8 kB
Release files / jalali_pandas-1.0.0.tar.gz
| Download URL | jalali_pandas-1.0.0.tar.gz |
|---|---|
| Size | 101.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4abddde083e91b0fd6a8762e54891d29e2ea3bc3c70eab1fbd19b84329318f9
|
|
BLAKE2b-256 checksum How to use checksums |
88602c95610031309944354b5381cb4e93725dcec0435266b5b4f5a59fdeb746
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 7, 2026.
Transparency logRelease files / jalali_pandas-1.0.0-py3-none-any.whl
| Download URL | jalali_pandas-1.0.0-py3-none-any.whl |
|---|---|
| Size | 78.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
97ef0aa40320585866da0f32b08742d0f52174ecfd9edbbdcbf8713c62f0ae6b
|
|
BLAKE2b-256 checksum How to use checksums |
1ee0294e4c929fadeee5f220f9a412637c2c916678daa8289d79c45edba4fc70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 7, 2026.
Transparency log