#PCalendar - Persian Calendar Library
A comprehensive Python library for working with the Persian (Solar Hijri) calendar. This library provides functionality for conversion between Persian and Gregorian calendars, date manipulation, and formatting.
## Features
- **Accurate Calendar Conversion**: Convert between Persian (Solar Hijri) and Gregorian calendars
- **Date Arithmetic**: Add/subtract time intervals and compare dates
- **Flexible Formatting**: Format dates with customizable Persian and English patterns
- **Leap Year Support**: Proper handling of Persian leap years
- **Timezone Aware**: Support for UTC and local timezone operations
- **Pure Python**: No external dependencies, uses only Python standard library
## Installation
```bash
pip install pcalendar
```
## Quick Start
```python
from pcalendar import from_gregorian_date, now, from_persian_date
# Convert Gregorian to Persian
persian_date = from_gregorian_date(2024, 1, 1)
print(f"Gregorian 2024/1/1 = Persian {persian_date.tm_year}/{persian_date.tm_mon + 1}/{persian_date.tm_mday}")
# Get current Persian date
today = now()
print(f"Today: {today.to_string('yyyy/MM/dd E')}")
# Create Persian date
nowruz = from_persian_date(1403, 1, 1) # Persian New Year 1403
print(f"Nowruz 1403: {nowruz.to_string('yyyy MMM dd E')}")
# Date arithmetic
tomorrow = today + 86400 # Add one day (86400 seconds)
print(f"Tomorrow: {tomorrow.to_string('yyyy/MM/dd')}")
```
## Usage Examples
### Creating Persian Dates
```python
from pcalendar import from_persian_date, from_gregorian_date, from_persian_components
# From Persian date
persian_date = from_persian_date(1400, 0, 1) # 1st Farvardin 1400 (months are 0-indexed)
# From Gregorian date
persian_from_greg = from_gregorian_date(2021, 3, 21)
# With time components
precise_date = from_persian_components(1400, 0, 1, 14, 30, 0, 0) # 2:30 PM
```
### Date Formatting
The library supports extensive formatting options:
```python
date = from_persian_date(1400, 0, 15)
# Various format examples
print(date.to_string("yyyy/MM/dd")) # 1400/01/15
print(date.to_string("yyyy MMM dd")) # 1400 فروردین 15
print(date.to_string("E, dd MMM yyyy")) # دوشنبه, 15 فروردین 1400
print(date.to_string("yyyy-MM-dd HH:mm:ss")) # 1400-01-15 00:00:00
```
### Format Specifiers
| Format | Description | Example |
|--------|-------------|---------|
| `yyyy` | 4-digit year | 1400 |
| `yy` | 2-digit year | 00 |
| `MMM` | Persian month name | فروردین |
| `MM` | 2-digit month | 01 |
| `M` | Month | 1 |
| `dd` | 2-digit day | 15 |
| `d` | Day | 15 |
| `E` | Persian weekday name | دوشنبه |
| `e` | Persian weekday short | د |
| `HH` | 24-hour format hour | 14 |
| `hh` | 12-hour format hour | 02 |
| `mm` | Minutes | 30 |
| `ss` | Seconds | 45 |
| `a` | AM/PM in Persian | ب.ظ |
### Date Arithmetic and Comparison
```python
from pcalendar import now
date1 = now()
date2 = date1 + 3600 # Add one hour
# Comparison
print(date2 > date1) # True
# Calculate difference
diff = date2 - date1 # Returns seconds
print(f"Difference: {diff} seconds")
# Convert to different timezones
utc_date = date1.to_utc()
local_date = utc_date.to_local()
```
### Working with Timestamps
```python
from pcalendar import at, at_utc
import time
# From Unix timestamp
timestamp = time.time()
persian_time = at(timestamp) # Local timezone
persian_utc = at_utc(timestamp) # UTC
# Convert to timestamp
unix_timestamp = persian_time.to_timestamp()
```
### Leap Year Handling
```python
from pcalendar import from_persian_date
# Check if a Persian year is leap
date = from_persian_date(1399, 0, 1) # Year 1399 is a leap year
print(date.is_leap()) # True
# Leap years have 30 days in Esfand (month 11), normal years have 29
leap_esfand = from_persian_date(1399, 11, 30) # Valid
normal_esfand = from_persian_date(1400, 11, 30) # None (invalid)
```
## Calendar System
The Persian calendar (Solar Hijri) used in Iran, Afghanistan, and other regions:
- **Year**: Starts with spring equinox (around March 21)
- **Months**:
- First 6 months: 31 days each (Farvardin to Shahrivar)
- Next 5 months: 30 days each (Mehr to Bahman)
- Last month (Esfand): 29 days (30 in leap years)
- **Week**: Starts with Shanbeh (Saturday)
- **Leap Years**: Follow a 33-year cycle
### Month Names
| Index | Persian Name | Transliteration | Days |
|-------|--------------|-----------------|------|
| 0 | فروردین | Farvardin | 31 |
| 1 | اردیبهشت | Ordibehesht | 31 |
| 2 | خرداد | Khordad | 31 |
| 3 | تیر | Tir | 31 |
| 4 | مرداد | Mordad | 31 |
| 5 | شهریور | Shahrivar | 31 |
| 6 | مهر | Mehr | 30 |
| 7 | آبان | Aban | 30 |
| 8 | آذر | Azar | 30 |
| 9 | دی | Dey | 30 |
| 10 | بهمن | Bahman | 30 |
| 11 | اسفند | Esfand | 29/30 |
### Weekday Names
| Index | Persian Name | Transliteration |
|-------|--------------|-----------------|
| 0 | شنبه | Shanbeh (Saturday) |
| 1 | یکشنبه | Yekshanbeh (Sunday) |
| 2 | دوشنبه | Doshanbeh (Monday) |
| 3 | سهشنبه | Seshhanbeh (Tuesday) |
| 4 | چهارشنبه | Chaharshanbeh (Wednesday) |
| 5 | پنجشنبه | Panjshanbeh (Thursday) |
| 6 | جمعه | Jomeh (Friday) |
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## Acknowledgments
- Persian calendar calculations based on Kazimierz M. Borkowski's algorithms
- Thanks to the Persian calendar research community
## License
This project is licensed under the GNU General Public License v3.0 see the `LICENSE` file for details.
Raw data
{
"_id": null,
"home_page": "https://codeberg.org/alimiracle/pcalendar",
"name": "pcalendar",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "Ali Miracle <alimiracle@riseup.net>",
"keywords": "persian, calendar, solar, hijri, shamsi, date, time, conversion",
"author": "Ali Miracle",
"author_email": "Ali Miracle <alimiracle@riseup.net>",
"download_url": "https://files.pythonhosted.org/packages/62/be/e642f9b31e403a8d3fbbe7a682a105fe2a75cf45b2bb519e64f11f9741ef/pcalendar-1.1.0.tar.gz",
"platform": null,
"description": "#PCalendar - Persian Calendar Library\n\nA comprehensive Python library for working with the Persian (Solar Hijri) calendar. This library provides functionality for conversion between Persian and Gregorian calendars, date manipulation, and formatting.\n\n## Features\n\n- **Accurate Calendar Conversion**: Convert between Persian (Solar Hijri) and Gregorian calendars\n- **Date Arithmetic**: Add/subtract time intervals and compare dates\n- **Flexible Formatting**: Format dates with customizable Persian and English patterns\n- **Leap Year Support**: Proper handling of Persian leap years\n- **Timezone Aware**: Support for UTC and local timezone operations\n- **Pure Python**: No external dependencies, uses only Python standard library\n\n## Installation\n\n```bash\npip install pcalendar\n```\n\n## Quick Start\n\n```python\nfrom pcalendar import from_gregorian_date, now, from_persian_date\n\n# Convert Gregorian to Persian\npersian_date = from_gregorian_date(2024, 1, 1)\nprint(f\"Gregorian 2024/1/1 = Persian {persian_date.tm_year}/{persian_date.tm_mon + 1}/{persian_date.tm_mday}\")\n\n# Get current Persian date\ntoday = now()\nprint(f\"Today: {today.to_string('yyyy/MM/dd E')}\")\n\n# Create Persian date\nnowruz = from_persian_date(1403, 1, 1) # Persian New Year 1403\nprint(f\"Nowruz 1403: {nowruz.to_string('yyyy MMM dd E')}\")\n\n# Date arithmetic\ntomorrow = today + 86400 # Add one day (86400 seconds)\nprint(f\"Tomorrow: {tomorrow.to_string('yyyy/MM/dd')}\")\n```\n\n## Usage Examples\n\n### Creating Persian Dates\n\n```python\nfrom pcalendar import from_persian_date, from_gregorian_date, from_persian_components\n\n# From Persian date\npersian_date = from_persian_date(1400, 0, 1) # 1st Farvardin 1400 (months are 0-indexed)\n\n# From Gregorian date\npersian_from_greg = from_gregorian_date(2021, 3, 21)\n\n# With time components\nprecise_date = from_persian_components(1400, 0, 1, 14, 30, 0, 0) # 2:30 PM\n```\n\n### Date Formatting\n\nThe library supports extensive formatting options:\n\n```python\ndate = from_persian_date(1400, 0, 15)\n\n# Various format examples\nprint(date.to_string(\"yyyy/MM/dd\")) # 1400/01/15\nprint(date.to_string(\"yyyy MMM dd\")) # 1400 \u0641\u0631\u0648\u0631\u062f\u06cc\u0646 15\nprint(date.to_string(\"E, dd MMM yyyy\")) # \u062f\u0648\u0634\u0646\u0628\u0647, 15 \u0641\u0631\u0648\u0631\u062f\u06cc\u0646 1400\nprint(date.to_string(\"yyyy-MM-dd HH:mm:ss\")) # 1400-01-15 00:00:00\n```\n\n### Format Specifiers\n\n| Format | Description | Example |\n|--------|-------------|---------|\n| `yyyy` | 4-digit year | 1400 |\n| `yy` | 2-digit year | 00 |\n| `MMM` | Persian month name | \u0641\u0631\u0648\u0631\u062f\u06cc\u0646 |\n| `MM` | 2-digit month | 01 |\n| `M` | Month | 1 |\n| `dd` | 2-digit day | 15 |\n| `d` | Day | 15 |\n| `E` | Persian weekday name | \u062f\u0648\u0634\u0646\u0628\u0647 |\n| `e` | Persian weekday short | \u062f |\n| `HH` | 24-hour format hour | 14 |\n| `hh` | 12-hour format hour | 02 |\n| `mm` | Minutes | 30 |\n| `ss` | Seconds | 45 |\n| `a` | AM/PM in Persian | \u0628.\u0638 |\n\n### Date Arithmetic and Comparison\n\n```python\nfrom pcalendar import now\n\ndate1 = now()\ndate2 = date1 + 3600 # Add one hour\n\n# Comparison\nprint(date2 > date1) # True\n\n# Calculate difference\ndiff = date2 - date1 # Returns seconds\nprint(f\"Difference: {diff} seconds\")\n\n# Convert to different timezones\nutc_date = date1.to_utc()\nlocal_date = utc_date.to_local()\n```\n\n### Working with Timestamps\n\n```python\nfrom pcalendar import at, at_utc\nimport time\n\n# From Unix timestamp\ntimestamp = time.time()\npersian_time = at(timestamp) # Local timezone\npersian_utc = at_utc(timestamp) # UTC\n\n# Convert to timestamp\nunix_timestamp = persian_time.to_timestamp()\n```\n\n### Leap Year Handling\n\n```python\nfrom pcalendar import from_persian_date\n\n# Check if a Persian year is leap\ndate = from_persian_date(1399, 0, 1) # Year 1399 is a leap year\nprint(date.is_leap()) # True\n\n# Leap years have 30 days in Esfand (month 11), normal years have 29\nleap_esfand = from_persian_date(1399, 11, 30) # Valid\nnormal_esfand = from_persian_date(1400, 11, 30) # None (invalid)\n```\n\n## Calendar System\n\nThe Persian calendar (Solar Hijri) used in Iran, Afghanistan, and other regions:\n\n- **Year**: Starts with spring equinox (around March 21)\n- **Months**: \n - First 6 months: 31 days each (Farvardin to Shahrivar)\n - Next 5 months: 30 days each (Mehr to Bahman)\n - Last month (Esfand): 29 days (30 in leap years)\n- **Week**: Starts with Shanbeh (Saturday)\n- **Leap Years**: Follow a 33-year cycle\n\n### Month Names\n\n| Index | Persian Name | Transliteration | Days |\n|-------|--------------|-----------------|------|\n| 0 | \u0641\u0631\u0648\u0631\u062f\u06cc\u0646 | Farvardin | 31 |\n| 1 | \u0627\u0631\u062f\u06cc\u0628\u0647\u0634\u062a | Ordibehesht | 31 |\n| 2 | \u062e\u0631\u062f\u0627\u062f | Khordad | 31 |\n| 3 | \u062a\u06cc\u0631 | Tir | 31 |\n| 4 | \u0645\u0631\u062f\u0627\u062f | Mordad | 31 |\n| 5 | \u0634\u0647\u0631\u06cc\u0648\u0631 | Shahrivar | 31 |\n| 6 | \u0645\u0647\u0631 | Mehr | 30 |\n| 7 | \u0622\u0628\u0627\u0646 | Aban | 30 |\n| 8 | \u0622\u0630\u0631 | Azar | 30 |\n| 9 | \u062f\u06cc | Dey | 30 |\n| 10 | \u0628\u0647\u0645\u0646 | Bahman | 30 |\n| 11 | \u0627\u0633\u0641\u0646\u062f | Esfand | 29/30 |\n\n### Weekday Names\n\n| Index | Persian Name | Transliteration |\n|-------|--------------|-----------------|\n| 0 | \u0634\u0646\u0628\u0647 | Shanbeh (Saturday) |\n| 1 | \u06cc\u06a9\u200c\u0634\u0646\u0628\u0647 | Yekshanbeh (Sunday) |\n| 2 | \u062f\u0648\u0634\u0646\u0628\u0647 | Doshanbeh (Monday) |\n| 3 | \u0633\u0647\u200c\u0634\u0646\u0628\u0647 | Seshhanbeh (Tuesday) |\n| 4 | \u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647 | Chaharshanbeh (Wednesday) |\n| 5 | \u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647 | Panjshanbeh (Thursday) |\n| 6 | \u062c\u0645\u0639\u0647 | Jomeh (Friday) |\n\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## Acknowledgments\n- Persian calendar calculations based on Kazimierz M. Borkowski's algorithms\n- Thanks to the Persian calendar research community\n\n## License\n\nThis project is licensed under the GNU General Public License v3.0 \u0097 see the `LICENSE` file for details.\n\n",
"bugtrack_url": null,
"license": "GPL-3.0-or-later",
"summary": "Persian Calendar Library - Python Implementation for Solar Hijri Calendar",
"version": "1.1.0",
"project_urls": {
"Bug Reports": "https://codeberg.org/alimiracle/pcalendar",
"Documentation": "https://codeberg.org/alimiracle/pcalendar#readme",
"Homepage": "https://codeberg.org/alimiracle/pcalendar",
"Repository": "https://codeberg.org/alimiracle/pcalendar"
},
"split_keywords": [
"persian",
" calendar",
" solar",
" hijri",
" shamsi",
" date",
" time",
" conversion"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "9551f56b199d2256d1e45bcc684b1fe5fa0a6d9884c1d651a0944392a56f6060",
"md5": "3d8e2a3911ee2020df8165f08a4c49fb",
"sha256": "5ca5819d62243377de70bdac9dfbbfa1712583e9e545e3054d2edcc7b2ae7998"
},
"downloads": -1,
"filename": "pcalendar-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3d8e2a3911ee2020df8165f08a4c49fb",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 22588,
"upload_time": "2025-07-29T17:46:42",
"upload_time_iso_8601": "2025-07-29T17:46:42.839903Z",
"url": "https://files.pythonhosted.org/packages/95/51/f56b199d2256d1e45bcc684b1fe5fa0a6d9884c1d651a0944392a56f6060/pcalendar-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "62bee642f9b31e403a8d3fbbe7a682a105fe2a75cf45b2bb519e64f11f9741ef",
"md5": "31e85f82945a1870671b4de30deeda3d",
"sha256": "4d7e02497c8893ddc9fa24c6deef88360720b08666e01b30da8ba2149ff18b6e"
},
"downloads": -1,
"filename": "pcalendar-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "31e85f82945a1870671b4de30deeda3d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 27459,
"upload_time": "2025-07-29T17:46:44",
"upload_time_iso_8601": "2025-07-29T17:46:44.484349Z",
"url": "https://files.pythonhosted.org/packages/62/be/e642f9b31e403a8d3fbbe7a682a105fe2a75cf45b2bb519e64f11f9741ef/pcalendar-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-29 17:46:44",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": true,
"codeberg_user": "alimiracle",
"codeberg_project": "pcalendar",
"lcname": "pcalendar"
}