{"id":13827652,"url":"https://github.com/majiidd/persiantools","last_synced_at":"2025-07-09T04:33:04.942Z","repository":{"id":37954682,"uuid":"282832737","full_name":"majiidd/persiantools","owner":"majiidd","description":"Jalali date and datetime with other tools","archived":false,"fork":false,"pushed_at":"2024-11-07T14:40:25.000Z","size":253,"stargazers_count":167,"open_issues_count":3,"forks_count":20,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-07T15:35:58.960Z","etag":null,"topics":["calendar","date","datetime","farsi","gregorian","iranian","jalali","jalali-datetime","jdate","jdatetime","persian","persiantools","python","shamsi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/majiidd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-27T08:03:29.000Z","updated_at":"2024-10-26T22:52:48.000Z","dependencies_parsed_at":"2024-02-19T19:31:52.992Z","dependency_job_id":"e30c4752-926f-403d-b479-4a9ccdbef8ff","html_url":"https://github.com/majiidd/persiantools","commit_stats":{"total_commits":190,"total_committers":11,"mean_commits":"17.272727272727273","dds":"0.39473684210526316","last_synced_commit":"e8ae12131f3d65c37b5828994cfec22753a93b64"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majiidd%2Fpersiantools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majiidd%2Fpersiantools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majiidd%2Fpersiantools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majiidd%2Fpersiantools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/majiidd","download_url":"https://codeload.github.com/majiidd/persiantools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225486379,"owners_count":17481885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","date","datetime","farsi","gregorian","iranian","jalali","jalali-datetime","jdate","jdatetime","persian","persiantools","python","shamsi"],"created_at":"2024-08-04T09:02:04.498Z","updated_at":"2025-07-09T04:33:04.933Z","avatar_url":"https://github.com/majiidd.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# PersianTools\n\n[![PyPI](https://img.shields.io/pypi/v/persiantools.svg)](https://pypi.org/project/persiantools/)\n![test workflow](https://github.com/majiidd/persiantools/actions/workflows/ci.yml/badge.svg)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/majiidd/persiantools/master.svg)](https://results.pre-commit.ci/latest/github/majiidd/persiantools/master)\n[![codecov](https://codecov.io/gh/majiidd/persiantools/branch/master/graph/badge.svg?token=Q990VL6FGW)](https://codecov.io/gh/majiidd/persiantools)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)\n[![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)\n\n`PersianTools` is a library written in Python for working with Jalali (Persian or Shamsi) dates and times, converting Persian and Arabic characters and digits, and converting numbers to Persian words.\n\n## Key Features\n\n- Conversion between Jalali and Gregorian dates/datetimes using Python's native datetime module.\n- Full support for operations such as `+`, `-`, `==`, `\u003e` and `\u003e=`.\n- Timezone-aware date and datetime handling.\n- Conversion between Persian, Arabic, and English characters and digits.\n- Conversion of numbers to their Persian word representation.\n\n## Install Package\n\nYou can install the package using `pip` with the following command:\n\n```bash\npython -m pip install persiantools\n```\n\n## Usage Guide\n\n### Date Operations\n\nThe `JalaliDate` object represents a date in the Jalali calendar.\n\n```python\n\u003e\u003e\u003e from persiantools.jdatetime import JalaliDate\n\u003e\u003e\u003e import datetime\n\n# Today's date\n\u003e\u003e\u003e JalaliDate.today()\nJalaliDate(1404, 3, 16, Jomeh)\n\n\u003e\u003e\u003e JalaliDate(1367, 2, 14)\nJalaliDate(1367, 2, 14, Chaharshanbeh)\n\n# Convert Gregorian to Jalali\n\u003e\u003e\u003e JalaliDate(datetime.date(1988, 5, 4))\nJalaliDate(1367, 2, 14, Chaharshanbeh)\n\n# Convert from Gregorian to Jalali using method\n\u003e\u003e\u003e JalaliDate.to_jalali(2013, 9, 16)\nJalaliDate(1392, 6, 25, Doshanbeh)\n\n# Convert from Jalali to Gregorian\n\u003e\u003e\u003e JalaliDate(1392, 6, 25).to_gregorian()\ndatetime.date(2013, 9, 16)\n\n# From ISO format\n\u003e\u003e\u003e JalaliDate.fromisoformat('1404-01-01')\nJalaliDate(1404, 1, 1, Jomeh)\n\n# Create a Jalali date from a Unix timestamp\n\u003e\u003e\u003e JalaliDate.fromtimestamp(578707200)\nJalaliDate(1367, 2, 14, Chaharshanbeh)\n\n# ISO format output\n\u003e\u003e\u003e JalaliDate(1367, 2, 14).isoformat()\n'1367-02-14'\n\n# Replace date parts\n\u003e\u003e\u003e JalaliDate(1400, 1, 1).replace(month=2, day=10)\nJalaliDate(1400, 2, 10, Jomeh)\n```\n#### Attributes and Methods\n\n```python\n\u003e\u003e\u003e date_obj = JalaliDate(1367, 2, 14)\n\n\u003e\u003e\u003e date_obj.year\n1367\n\u003e\u003e\u003e date_obj.month\n2\n\u003e\u003e\u003e date_obj.day\n14\n\n# Weekday (Saturday is 0 and Friday is 6)\n\u003e\u003e\u003e date_obj.weekday() # 1367/2/14 is Chaharshanbeh (Wednesday)\n4\n\n# ISO Weekday (Monday is 1 and Sunday is 7)\n\u003e\u003e\u003e date_obj.isoweekday()\n5\n\n\u003e\u003e\u003e date_obj.week_of_year()\n7\n\n# ISO Calendar (ISO year, ISO week number, ISO weekday)\n\u003e\u003e\u003e date_obj.isocalendar()\n(1367, 7, 5)\n```\n\n### Datetime Operations\n\nThe `JalaliDateTime` object represents a date and time in the Jalali calendar.\n\n```python\n\u003e\u003e\u003e from persiantools.jdatetime import JalaliDateTime\n\u003e\u003e\u003e import datetime, pytz\n\n# Current Jalali datetime\n\u003e\u003e\u003e JalaliDateTime.now()\nJalaliDateTime(1404, 3, 16, 2, 17, 14, 907909)\n\n# Current Jalali datetime (timezone-aware)\n\u003e\u003e\u003e JalaliDateTime.now(pytz.timezone(\"Asia/Tehran\"))\nJalaliDateTime(1404, 3, 16, 2, 17, 14, 907909, tzinfo=\u003cDstTzInfo 'Asia/Tehran' +0330+3:30:00 STD\u003e)\n\n# Current UTC Jalali datetime\n\u003e\u003e\u003e JalaliDateTime.utcnow()\nJalaliDateTime(1404, 3, 15, 22, 56, 49, 892339, tzinfo=datetime.timezone.utc)\n\n# Convert Jalali datetime to Gregorian\n\u003e\u003e\u003e JalaliDateTime.now().to_gregorian()\ndatetime.datetime(2025, 6, 6, 2, 17, 14, 907909)\n\n# Convert Gregorian datetime to Jalali (From a datetime.datetime object)\n\u003e\u003e\u003e dt_gregorian = datetime.datetime(1988, 5, 4, 14, 30, 15)\n\u003e\u003e\u003e JalaliDateTime(dt_gregorian)\nJalaliDateTime(1367, 2, 14, 14, 30, 15)\n\n# Replace datetime parts\n\u003e\u003e\u003e JalaliDateTime(1400, 1, 1, 12, 0, 0).replace(hour=15, minute=30, microsecond=10)\nJalaliDateTime(1400, 1, 1, 15, 30, 0, 10)\n\n# Timezone conversion\n\u003e\u003e\u003e tehran_tz = pytz.timezone(\"Asia/Tehran\")\n\u003e\u003e\u003e utc_tz = pytz.utc\n\u003e\u003e\u003e dt_utc = JalaliDateTime.now(utc_tz)\n\u003e\u003e\u003e dt_tehran = dt_utc.astimezone(tehran_tz)\n\u003e\u003e\u003e dt_utc\nJalaliDateTime(1404, 3, 15, 22, 54, 8, 835877, tzinfo=\u003cUTC\u003e)\n\u003e\u003e\u003e dt_tehran\nJalaliDateTime(1404, 3, 16, 2, 24, 8, 835877, tzinfo=\u003cDstTzInfo 'Asia/Tehran' +0330+3:30:00 STD\u003e)\n```\n\n#### Attributes and Methods\n\n```python\n\u003e\u003e\u003e dt_obj = JalaliDateTime(1367, 2, 14, 14, 30, 15, 123, tzinfo=pytz.utc)\n\n\u003e\u003e\u003e dt_obj.year\n1367\n\u003e\u003e\u003e dt_obj.month\n2\n\u003e\u003e\u003e dt_obj.day\n14\n\u003e\u003e\u003e dt_obj.hour\n14\n\u003e\u003e\u003e dt_obj.minute\n30\n\u003e\u003e\u003e dt_obj.second\n15\n\u003e\u003e\u003e dt_obj.microsecond\n123\n\u003e\u003e\u003e dt_obj.tzinfo\n\u003cUTC\u003e\n\n# Date part as datetime.date (Gregorian)\n\u003e\u003e\u003e dt_obj.date()\ndatetime.date(1988, 5, 4)\n\n# JalaliDate object\n\u003e\u003e\u003e dt_obj.jdate()\nJalaliDate(1367, 2, 14, Chaharshanbeh)\n\n# Time part as datetime.time\n\u003e\u003e\u003e dt_obj.time()\ndatetime.time(14, 30, 15, 123)\n```\n\n### Formatting\n\nBased on python `strftime()` behavior\n\n```python\n\u003e\u003e\u003e from persiantools.jdatetime import JalaliDateTime\n\u003e\u003e\u003e import pytz\n\n\u003e\u003e\u003e dt = JalaliDateTime(1367, 2, 14, 14, 30, 0, tzinfo=pytz.timezone(\"Asia/Tehran\"))\n\n\u003e\u003e\u003e dt.strftime(\"%Y/%m/%d %H:%M:%S\")\n'1367/02/14 14:30:00'\n\n\u003e\u003e\u003e dt.strftime(\"%c\", locale='fa')\n'چهارشنبه ۱۴ اردیبهشت ۱۳۶۷ ۱۴:۳۰:۰۰'\n```\n\n### Digits and Character Conversion\n\nThis section covers converting between different numeral systems (Persian, Arabic, English) and converting numbers to their Persian word representations. It also includes utilities for converting between Persian and Arabic characters.\n\n```python\n\u003e\u003e\u003e from persiantools import digits\n\n# Convert English digits to Persian\n\u003e\u003e\u003e digits.en_to_fa(\"0987654321\")\n'۰۹۸۷۶۵۴۳۲۱'\n\n# Convert Arabic digits to Persian\n\u003e\u003e\u003e digits.ar_to_fa(\"٠٩٨٧٦٥٤٣٢١\")\n'۰۹۸۷۶۵۴۳۲۱'\n\n# Convert Persian digits to English\n\u003e\u003e\u003e digits.fa_to_en(\"۰۹۸۷۶۵۴۳۲۱\")\n'0987654321'\n\n# Convert Persian digits to Arabic\n\u003e\u003e\u003e digits.fa_to_ar(\"۰۹۸۷۶۵۴۳۲۱\")\n'٠٩٨٧٦٥٤٣٢١'\n```\n\n#### Numbers to Words\n\nConvert numerical values (integers and floats) into Persian words.\n\n```python\n\u003e\u003e\u003e from persiantools import digits\n\n\u003e\u003e\u003e digits.to_word(9512026)\n'نه میلیون و پانصد و دوازده هزار و بیست و شش'\n\n\u003e\u003e\u003e digits.to_word(15.007)\n'پانزده و هفت هزارم'\n\n\u003e\u003e\u003e digits.to_word(-123.45)\n'منفی یکصد و بیست و سه و چهل و پنج صدم'\n\n\u003e\u003e\u003e digits.to_word(0)\n'صفر'\n```\n\n#### Character Conversion\n\nFunctions for converting specific Arabic characters to their Persian equivalents and vice-versa. This is often needed due to differences in the Unicode representation of similar-looking characters (e.g., `ک` vs `ك`, `ی` vs `ي`).\n\n```python\n\u003e\u003e\u003e from persiantools import characters\n\n\u003e\u003e\u003e characters.ar_to_fa(\"كيك\") # Input uses Arabic Kaf (U+0643) and Yeh (U+064A)\n'کیک' # Output uses Persian Keh (U+06A9) and Yeh (U+06CC)\n\n\u003e\u003e\u003e characters.fa_to_ar(\"کیک\")\n'كيك'\n```\n\n### Operators\n\nBoth `JalaliDate` and `JalaliDateTime` objects support standard comparison operators (`\u003c`, `\u003c=`, `==`, `!=`, `\u003e`, `\u003e=`) and arithmetic operations (`+`, `-` with `datetime.timedelta` objects). They can also be compared with their Gregorian counterparts (`datetime.date` and `datetime.datetime`).\n\n```python\n\u003e\u003e\u003e from persiantools.jdatetime import JalaliDate, JalaliDateTime\n\u003e\u003e\u003e import datetime\n\n\u003e\u003e\u003e JalaliDate(1367, 2, 14) == JalaliDate(datetime.date(1988, 5, 4))\nTrue\n\n\u003e\u003e\u003e JalaliDateTime(1367, 2, 14, 4, 30) \u003e= JalaliDateTime(1368, 2, 14, 1, 0)\nFalse\n\n\u003e\u003e\u003e JalaliDate(1367, 2, 14) == datetime.date(1988, 5, 4)\nTrue\n\n\u003e\u003e\u003e JalaliDate(1395, 2, 14) + datetime.timedelta(days=38)\nJalaliDate(1395, 3, 21, Jomeh)\n\n\u003e\u003e\u003e JalaliDateTime(1395, 12, 30) - JalaliDateTime(1395, 1, 1)\ndatetime.timedelta(365)\n\n\u003e\u003e\u003e JalaliDateTime(1395, 2, 14, 12, 0, 0) + datetime.timedelta(hours=5, minutes=30)\nJalaliDateTime(1395, 2, 14, 17, 30)\n```\n\n### Serializing and Deserializing\n\n`JalaliDate` and `JalaliDateTime` objects can be serialized (pickled) and deserialized (unpickled) using Python's standard `pickle` module. This allows for storing these objects or transmitting them.\n\n```python\n\u003e\u003e\u003e from persiantools.jdatetime import JalaliDate\n\u003e\u003e\u003e import pickle\n\n# Serialize a Jalali date to a file\n\u003e\u003e\u003e with open(\"save.p\", \"wb\") as file:\n\u003e\u003e\u003e     pickle.dump(JalaliDate(1367, 2, 14), file)\n\n# Deserialize from a file\n\u003e\u003e\u003e with open(\"save.p\", \"rb\") as file:\n\u003e\u003e\u003e     jalali = pickle.load(file)\n\u003e\u003e\u003e jalali\nJalaliDate(1367, 2, 14, Chaharshanbeh)\n```\n\n## Support This Project\nIf you find this project helpful and would like to support its continued development, please consider donating.\n\n*   **Bitcoin (BTC):** `bc1qg5rp7ymznc98wmhltzvpwl2dvfuvjr33m4hy77`\n*   **Tron (TRX):** `TDd63bVWZDBHmwVNFgJ6T2WdWmk9z7PBLg`\n*   **Stellar (XLM):** `GDSFPPLY34QSAOTOP4DQDXAI2YDRNRIADZHTN3HCGMQXRLIGPYOEH7L5`\n*   **Solana (SOL):** `CXHKgCBqBYy1hbZKGqaSmMzQoTC4Wx2v8QfL9Z7JBo3A`\n*   **Dogecoin (DOGE):** `DRZ2QLuXfa5vV1AG83K3XHfYXAHj9b4h4V`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajiidd%2Fpersiantools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmajiidd%2Fpersiantools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajiidd%2Fpersiantools/lists"}