Skip to main content

Jalali date and datetime with other tools

Project description

PersianTools

PyPI test workflow pre-commit.ci status codecov PyPI - Python Version PyPI - License

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.

Key Features

  • Conversion between Jalali and Gregorian dates/datetimes using Python's native datetime module.
  • Full support for operations such as +, -, ==, > and >=.
  • Timezone-aware date and datetime handling.
  • Conversion between Persian, Arabic, and English characters and digits.
  • Conversion of numbers to their Persian word representation.

Install Package

You can install the package using pip with the following command:

python -m pip install persiantools

Usage Guide

Date Operations

The JalaliDate object represents a date in the Jalali calendar.

>>> from persiantools.jdatetime import JalaliDate
>>> import datetime

# Today's date
>>> JalaliDate.today()
JalaliDate(1404, 3, 16, Jomeh)

>>> JalaliDate(1367, 2, 14)
JalaliDate(1367, 2, 14, Chaharshanbeh)

# Convert Gregorian to Jalali
>>> JalaliDate(datetime.date(1988, 5, 4))
JalaliDate(1367, 2, 14, Chaharshanbeh)

# Convert from Gregorian to Jalali using method
>>> JalaliDate.to_jalali(2013, 9, 16)
JalaliDate(1392, 6, 25, Doshanbeh)

# Convert from Jalali to Gregorian
>>> JalaliDate(1392, 6, 25).to_gregorian()
datetime.date(2013, 9, 16)

# From ISO format
>>> JalaliDate.fromisoformat('1404-01-01')
JalaliDate(1404, 1, 1, Jomeh)

# Create a Jalali date from a Unix timestamp
>>> JalaliDate.fromtimestamp(578707200)
JalaliDate(1367, 2, 14, Chaharshanbeh)

# ISO format output
>>> JalaliDate(1367, 2, 14).isoformat()
'1367-02-14'

# Replace date parts
>>> JalaliDate(1400, 1, 1).replace(month=2, day=10)
JalaliDate(1400, 2, 10, Jomeh)

Attributes and Methods

>>> date_obj = JalaliDate(1367, 2, 14)

>>> date_obj.year
1367
>>> date_obj.month
2
>>> date_obj.day
14

# Weekday (Saturday is 0 and Friday is 6)
>>> date_obj.weekday() # 1367/2/14 is Chaharshanbeh (Wednesday)
4

# ISO Weekday (Monday is 1 and Sunday is 7)
>>> date_obj.isoweekday()
5

>>> date_obj.week_of_year()
7

# ISO Calendar (ISO year, ISO week number, ISO weekday)
>>> date_obj.isocalendar()
(1367, 7, 5)

Datetime Operations

The JalaliDateTime object represents a date and time in the Jalali calendar.

>>> from persiantools.jdatetime import JalaliDateTime
>>> import datetime

# Current Jalali datetime
>>> JalaliDateTime.now()
JalaliDateTime(1404, 3, 16, 2, 17, 14, 907909)

>>> from zoneinfo import ZoneInfo
>>> JalaliDateTime.now(ZoneInfo("Asia/Tehran"))
JalaliDateTime(1404, 3, 16, 2, 17, 14, 907909, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tehran'))

# Current UTC Jalali datetime
>>> JalaliDateTime.utcnow()
JalaliDateTime(1404, 3, 15, 22, 56, 49, 892339, tzinfo=datetime.timezone.utc)

# Convert Jalali datetime to Gregorian
>>> JalaliDateTime.now().to_gregorian()
datetime.datetime(2025, 6, 6, 2, 17, 14, 907909)

# Convert Gregorian datetime to Jalali (From a datetime.datetime object)
>>> dt_gregorian = datetime.datetime(1988, 5, 4, 14, 30, 15)
>>> JalaliDateTime(dt_gregorian)
JalaliDateTime(1367, 2, 14, 14, 30, 15)

# Replace datetime parts
>>> JalaliDateTime(1400, 1, 1, 12, 0, 0).replace(hour=15, minute=30, microsecond=10)
JalaliDateTime(1400, 1, 1, 15, 30, 0, 10)

# Timezone conversion
>>> from zoneinfo import ZoneInfo
>>> tehran_tz = ZoneInfo("Asia/Tehran")
>>> utc_tz = datetime.timezone.utc
>>> dt_utc = JalaliDateTime.now(utc_tz)
>>> dt_tehran = dt_utc.astimezone(tehran_tz)
>>> dt_utc
JalaliDateTime(1404, 3, 15, 22, 54, 8, 835877, tzinfo=datetime.timezone.utc)
>>> dt_tehran
JalaliDateTime(1404, 3, 16, 2, 24, 8, 835877, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tehran'))

Attributes and Methods

>>> dt_obj = JalaliDateTime(1367, 2, 14, 14, 30, 15, 123, tzinfo=datetime.timezone.utc)

>>> dt_obj.year
1367
>>> dt_obj.month
2
>>> dt_obj.day
14
>>> dt_obj.hour
14
>>> dt_obj.minute
30
>>> dt_obj.second
15
>>> dt_obj.microsecond
123
>>> dt_obj.tzinfo
datetime.timezone.utc

# Date part as datetime.date (Gregorian)
>>> dt_obj.date()
datetime.date(1988, 5, 4)

# JalaliDate object
>>> dt_obj.jdate()
JalaliDate(1367, 2, 14, Chaharshanbeh)

# Time part as datetime.time
>>> dt_obj.time()
datetime.time(14, 30, 15, 123)

Formatting

Based on python strftime() behavior

>>> from persiantools.jdatetime import JalaliDateTime
>>> from zoneinfo import ZoneInfo

>>> dt = JalaliDateTime(1367, 2, 14, 14, 30, 0, tzinfo=ZoneInfo("Asia/Tehran"))

>>> dt.strftime("%Y/%m/%d %H:%M:%S")
'1367/02/14 14:30:00'

>>> dt.strftime("%c", locale='fa')
'چهارشنبه ۱۴ اردیبهشت ۱۳۶۷ ۱۴:۳۰:۰۰'

Digits and Character Conversion

This 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.

>>> from persiantools import digits

# Convert English digits to Persian
>>> digits.en_to_fa("0987654321")
'۰۹۸۷۶۵۴۳۲۱'

# Convert Arabic digits to Persian
>>> digits.ar_to_fa("٠٩٨٧٦٥٤٣٢١")
'۰۹۸۷۶۵۴۳۲۱'

# Convert Persian digits to English
>>> digits.fa_to_en("۰۹۸۷۶۵۴۳۲۱")
'0987654321'

# Convert Persian digits to Arabic
>>> digits.fa_to_ar("۰۹۸۷۶۵۴۳۲۱")
'٠٩٨٧٦٥٤٣٢١'

Numbers to Words

Convert numerical values (integers and floats) into Persian words.

>>> from persiantools import digits

>>> digits.to_word(9512026)
'نه میلیون و پانصد و دوازده هزار و بیست و شش'

>>> digits.to_word(15.007)
'پانزده و هفت هزارم'

>>> digits.to_word(-123.45)
'منفی یکصد و بیست و سه و چهل و پنج صدم'

>>> digits.to_word(0)
'صفر'

Character Conversion

Functions 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 ي).

>>> from persiantools import characters

>>> characters.ar_to_fa("كيك") # Input uses Arabic Kaf (U+0643) and Yeh (U+064A)
'کیک' # Output uses Persian Keh (U+06A9) and Yeh (U+06CC)

>>> characters.fa_to_ar("کیک")
'كيك'

Operators

Both JalaliDate and JalaliDateTime objects support standard comparison operators (<, <=, ==, !=, >, >=) and arithmetic operations (+, - with datetime.timedelta objects). They can also be compared with their Gregorian counterparts (datetime.date and datetime.datetime).

>>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
>>> import datetime

>>> JalaliDate(1367, 2, 14) == JalaliDate(datetime.date(1988, 5, 4))
True

>>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1368, 2, 14, 1, 0)
False

>>> JalaliDate(1367, 2, 14) == datetime.date(1988, 5, 4)
True

>>> JalaliDate(1395, 2, 14) + datetime.timedelta(days=38)
JalaliDate(1395, 3, 21, Jomeh)

>>> JalaliDateTime(1395, 12, 30) - JalaliDateTime(1395, 1, 1)
datetime.timedelta(365)

>>> JalaliDateTime(1395, 2, 14, 12, 0, 0) + datetime.timedelta(hours=5, minutes=30)
JalaliDateTime(1395, 2, 14, 17, 30)

Serializing and Deserializing

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.

>>> from persiantools.jdatetime import JalaliDate
>>> import pickle

# Serialize a Jalali date to a file
>>> with open("save.p", "wb") as file:
>>>     pickle.dump(JalaliDate(1367, 2, 14), file)

# Deserialize from a file
>>> with open("save.p", "rb") as file:
>>>     jalali = pickle.load(file)
>>> jalali
JalaliDate(1367, 2, 14, Chaharshanbeh)

Support This Project

If you find this project helpful and would like to support its continued development, please consider donating.

  • Bitcoin (BTC): bc1qg5rp7ymznc98wmhltzvpwl2dvfuvjr33m4hy77
  • Ethereum (ETH): 0xC7D6bf306E456632764D0aD111C8dBBb43a3B9ad
  • Tron (TRX): TDd63bVWZDBHmwVNFgJ6T2WdWmk9z7PBLg
  • Stellar (XLM): GDSFPPLY34QSAOTOP4DQDXAI2YDRNRIADZHTN3HCGMQXRLIGPYOEH7L5
  • Solana (SOL): CXHKgCBqBYy1hbZKGqaSmMzQoTC4Wx2v8QfL9Z7JBo3A
  • Dogecoin (DOGE): DRZ2QLuXfa5vV1AG83K3XHfYXAHj9b4h4V

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

persiantools-5.5.0.tar.gz (41.1 kB view details)

Uploaded Source

Built Distribution

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

persiantools-5.5.0-py3-none-any.whl (25.1 kB view details)

Uploaded Python 3

File details

Details for the file persiantools-5.5.0.tar.gz.

File metadata

  • Download URL: persiantools-5.5.0.tar.gz
  • Upload date:
  • Size: 41.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for persiantools-5.5.0.tar.gz
Algorithm Hash digest
SHA256 5de8043a80bf3f08e36c10b081a8a5eb9675ffb23b69520de83f2a5d561d5b0a
MD5 6e507b84da54874485c60134c435f5e6
BLAKE2b-256 558836e19ec2c02fdc2706ddf74f1e29d36c01d6646c257a5b38905ecc5dadf7

See more details on using hashes here.

Provenance

The following attestation bundles were made for persiantools-5.5.0.tar.gz:

Publisher: ci.yml on majiidd/persiantools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file persiantools-5.5.0-py3-none-any.whl.

File metadata

  • Download URL: persiantools-5.5.0-py3-none-any.whl
  • Upload date:
  • Size: 25.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for persiantools-5.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e6bda6e384d8efb9797f1b8cd71ba5c19e3ca7d374d4dea16941d496c0eeee2d
MD5 d8c1b0b98864e651c0128435f309c9c2
BLAKE2b-256 95298337889aedf5f35d1faa3845e188fa9ffb7d8134ab884482a11d03fae24f

See more details on using hashes here.

Provenance

The following attestation bundles were made for persiantools-5.5.0-py3-none-any.whl:

Publisher: ci.yml on majiidd/persiantools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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