hijri-datetime 0.1.1__py3-none-any.whl → 0.2.3.post0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,97 @@
1
- from .hello import say_hello
1
+ """
2
+ hijri-datetime: Pythonic Hijri datetime operations.
2
3
 
3
- __all__ = ["say_hello"]
4
+ A comprehensive library for working with Hijri (Islamic) calendar dates,
5
+ providing seamless conversion between Hijri, Gregorian, and Jalali calendars.
6
+ """
7
+ """
8
+ hijri-datetime: Pythonic Hijri datetime operations.
9
+ """
10
+
11
+ # Version management with fallback
12
+ try:
13
+ from _version import __version__
14
+ except ImportError:
15
+ # Fallback version when setuptools_scm hasn't run yet
16
+ try:
17
+ from importlib.metadata import version
18
+ __version__ = version("hijri-datetime")
19
+ except ImportError:
20
+ # Ultimate fallback
21
+ __version__ = "unknown"
22
+
23
+ # Main exports
24
+ from .date import (
25
+ HijriDate,
26
+ )
27
+
28
+ from .datetime import (
29
+ HijriDateTime,
30
+ )
31
+
32
+
33
+ from .time import (
34
+ HijriTime,
35
+ )
36
+
37
+
38
+ from .range import (
39
+ HijriDateRange,
40
+ )
41
+
42
+ from .conversion import (
43
+ hijri_to_gregorian,
44
+ gregorian_to_hijri,
45
+ hijri_to_jalali,
46
+ jalali_to_hijri,
47
+ )
48
+
49
+ from .exceptions import (
50
+ HijriError,
51
+ InvalidHijriDate,
52
+ ConversionError,
53
+ )
54
+
55
+ from .utils import (
56
+ is_valid_hijri_date,
57
+ get_hijri_month_name,
58
+ get_hijri_weekday_name,
59
+ )
60
+
61
+ # Convenience imports
62
+ from .constants import (
63
+ HIJRI_MONTHS,
64
+ HIJRI_WEEKDAYS,
65
+ ISLAMIC_EPOCH,
66
+ )
67
+
68
+ __all__ = [
69
+ "__version__",
70
+ # Core classes
71
+ "HijriDate",
72
+ "HijriDateTime",
73
+ "HijriTime",
74
+ "HijriDateRange",
75
+ # Conversion functions
76
+ "hijri_to_gregorian",
77
+ "gregorian_to_hijri",
78
+ "hijri_to_jalali",
79
+ "jalali_to_hijri",
80
+ # Exceptions
81
+ "HijriError",
82
+ "InvalidHijriDate",
83
+ "ConversionError",
84
+ # Utilities
85
+ "is_valid_hijri_date",
86
+ "get_hijri_month_name",
87
+ "get_hijri_weekday_name",
88
+ # Constants
89
+ "HIJRI_MONTHS",
90
+ "HIJRI_WEEKDAYS",
91
+ "ISLAMIC_EPOCH",
92
+ ]
93
+
94
+ # Package metadata
95
+ __author__ = "m.lotfi"
96
+ __email__ = "m.lotfi@email.com"
97
+ __description__ = "Pythonic Hijri datetime — handle full & partial dates, ranges, and seamless Gregorian & Jalali conversion."
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.2.3.post0'
32
+ __version_tuple__ = version_tuple = (0, 2, 3, 'post0')
33
+
34
+ __commit_id__ = commit_id = None
@@ -0,0 +1,64 @@
1
+ """Constants for Hijri calendar."""
2
+
3
+ from datetime import date
4
+
5
+ # Hijri month names in Arabic and English
6
+ HIJRI_MONTHS = [
7
+ "Muharram",
8
+ "Safar",
9
+ "Rabi' al-awwal",
10
+ "Rabi' al-thani",
11
+ "Jumada al-awwal",
12
+ "Jumada al-thani",
13
+ "Rajab",
14
+ "Sha'ban",
15
+ "Ramadan",
16
+ "Shawwal",
17
+ "Dhu al-Qi'dah",
18
+ "Dhu al-Hijjah"
19
+ ]
20
+
21
+ HIJRI_MONTHS_ARABIC = [
22
+ "محرم",
23
+ "صفر",
24
+ "ربيع الأول",
25
+ "ربيع الثاني",
26
+ "جمادى الأولى",
27
+ "جمادى الثانية",
28
+ "رجب",
29
+ "شعبان",
30
+ "رمضان",
31
+ "شوال",
32
+ "ذو القعدة",
33
+ "ذو الحجة"
34
+ ]
35
+
36
+ # Weekday names
37
+ HIJRI_WEEKDAYS = [
38
+ "Saturday", # Sabt
39
+ "Sunday", # Ahad
40
+ "Monday", # Ithnayn
41
+ "Tuesday", # Thulatha
42
+ "Wednesday", # Arbi'a
43
+ "Thursday", # Khamis
44
+ "Friday" # Jumu'ah
45
+ ]
46
+
47
+ HIJRI_WEEKDAYS_ARABIC = [
48
+ "السبت",
49
+ "الأحد",
50
+ "الإثنين",
51
+ "الثلاثاء",
52
+ "الأربعاء",
53
+ "الخميس",
54
+ "الجمعة"
55
+ ]
56
+
57
+ # Islamic epoch (July 16, 622 CE in Gregorian calendar)
58
+ ISLAMIC_EPOCH = date(622, 7, 16)
59
+
60
+ # Days in each Hijri month (simplified - actual lengths vary)
61
+ HIJRI_MONTH_DAYS = [30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29]
62
+
63
+ # Leap year pattern for Hijri calendar (30-year cycle)
64
+ HIJRI_LEAP_YEARS = [2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29]
hijri_datetime/date.py CHANGED
@@ -0,0 +1,135 @@
1
+ """Core Hijri date and time classes."""
2
+
3
+ from datetime import date, datetime, time
4
+ from typing import Optional, Union, Tuple
5
+ import calendar
6
+
7
+ from exceptions import InvalidHijriDate
8
+ from constants import HIJRI_MONTHS, HIJRI_WEEKDAYS
9
+
10
+
11
+ class HijriDate:
12
+ """Represents a Hijri calendar date."""
13
+
14
+ def __init__(self, year: int, month: int, day: int):
15
+ """Initialize a Hijri date.
16
+
17
+ Args:
18
+ year: Hijri year
19
+ month: Hijri month (1-12)
20
+ day: Hijri day (1-30)
21
+
22
+ Raises:
23
+ InvalidHijriDate: If the date is invalid
24
+ """
25
+ if not self._is_valid_date(year, month, day):
26
+ raise InvalidHijriDate(f"Invalid Hijri date: {year}-{month}-{day}")
27
+
28
+ self.year = year
29
+ self.month = month
30
+ self.day = day
31
+
32
+ def _is_valid_date(self, year: int, month: int, day: int) -> bool:
33
+ """Check if the given Hijri date is valid."""
34
+ if not (1 <= month <= 12):
35
+ return False
36
+ if not (1 <= day <= 30):
37
+ return False
38
+ # Add more sophisticated validation here
39
+ return True
40
+
41
+ def __repr__(self) -> str:
42
+ return f"HijriDate({self.year}, {self.month}, {self.day})"
43
+
44
+ def __str__(self) -> str:
45
+ return f"{self.year:04d}-{self.month:02d}-{self.day:02d}"
46
+
47
+ @property
48
+ def month_name(self) -> str:
49
+ """Get the name of the Hijri month."""
50
+ return HIJRI_MONTHS[self.month - 1]
51
+
52
+ def to_gregorian(self) -> date:
53
+ """Convert to Gregorian date."""
54
+ from .converter import hijri_to_gregorian
55
+ return hijri_to_gregorian(self)
56
+
57
+ def to_jalali(self):
58
+ """Convert to Jalali date."""
59
+ from .converter import hijri_to_jalali
60
+ return hijri_to_jalali(self)
61
+
62
+
63
+ class HijriDateTime:
64
+ """Represents a Hijri calendar datetime."""
65
+
66
+ def __init__(self, year: int, month: int, day: int,
67
+ hour: int = 0, minute: int = 0, second: int = 0):
68
+ """Initialize a Hijri datetime."""
69
+ self.date = HijriDate(year, month, day)
70
+ self.time = HijriTime(hour, minute, second)
71
+
72
+ @property
73
+ def year(self) -> int:
74
+ return self.date.year
75
+
76
+ @property
77
+ def month(self) -> int:
78
+ return self.date.month
79
+
80
+ @property
81
+ def day(self) -> int:
82
+ return self.date.day
83
+
84
+ def __repr__(self) -> str:
85
+ return f"HijriDateTime({self.year}, {self.month}, {self.day}, {self.time.hour}, {self.time.minute}, {self.time.second})"
86
+
87
+
88
+ class HijriTime:
89
+ """Represents a time in the Hijri calendar context."""
90
+
91
+ def __init__(self, hour: int = 0, minute: int = 0, second: int = 0):
92
+ """Initialize a Hijri time."""
93
+ if not (0 <= hour <= 23):
94
+ raise ValueError("Hour must be between 0 and 23")
95
+ if not (0 <= minute <= 59):
96
+ raise ValueError("Minute must be between 0 and 59")
97
+ if not (0 <= second <= 59):
98
+ raise ValueError("Second must be between 0 and 59")
99
+
100
+ self.hour = hour
101
+ self.minute = minute
102
+ self.second = second
103
+
104
+
105
+ class HijriDateRange:
106
+ """Represents a range of Hijri dates."""
107
+
108
+ def __init__(self, start: HijriDate, end: HijriDate):
109
+ """Initialize a Hijri date range."""
110
+ if start > end:
111
+ raise ValueError("Start date must be before or equal to end date")
112
+ self.start = start
113
+ self.end = end
114
+
115
+ def __contains__(self, date: HijriDate) -> bool:
116
+ """Check if a date is within the range."""
117
+ return self.start <= date <= self.end
118
+
119
+ def __iter__(self):
120
+ """Iterate over dates in the range."""
121
+ current = self.start
122
+ while current <= self.end:
123
+ yield current
124
+ # Add one day (simplified)
125
+ current = self._add_one_day(current)
126
+
127
+ def _add_one_day(self, date: HijriDate) -> HijriDate:
128
+ """Add one day to a Hijri date (simplified implementation)."""
129
+ # This is a simplified version - you'd need proper calendar logic
130
+ if date.day < 30: # Assuming max 30 days per month for simplicity
131
+ return HijriDate(date.year, date.month, date.day + 1)
132
+ elif date.month < 12:
133
+ return HijriDate(date.year, date.month + 1, 1)
134
+ else:
135
+ return HijriDate(date.year + 1, 1, 1)
@@ -0,0 +1,26 @@
1
+ """Custom exceptions for hijri-datetime package."""
2
+
3
+
4
+ class HijriError(Exception):
5
+ """Base exception for hijri-datetime package."""
6
+ pass
7
+
8
+
9
+ class InvalidHijriDate(HijriError):
10
+ """Raised when an invalid Hijri date is provided."""
11
+ pass
12
+
13
+
14
+ class ConversionError(HijriError):
15
+ """Raised when calendar conversion fails."""
16
+ pass
17
+
18
+
19
+ class InvalidHijriTime(HijriError):
20
+ """Raised when an invalid Hijri time is provided."""
21
+ pass
22
+
23
+
24
+ class DateRangeError(HijriError):
25
+ """Raised when there's an error with date ranges."""
26
+ pass
hijri_datetime/time.py ADDED
File without changes
@@ -1,13 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hijri-datetime
3
- Version: 0.1.1
3
+ Version: 0.2.3.post0
4
+ Summary: Pythonic Hijri datetime — handle full & partial dates, ranges, and seamless Gregorian & Jalali conversion.
4
5
  Author-email: "m.lotfi" <m.lotfi@email.com>
5
6
  Maintainer-email: "m.lotfi" <m.lotfi@email.com>
6
- License: MIT
7
- Keywords: python,package,modules,portable,hijri,islamic,calendar,datetime
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Development Status :: 3 - Alpha
7
+ License: GPL version 3
8
+ Project-URL: Homepage, https://github.com/mlotfic/hijri-datetime
9
+ Project-URL: Documentation, https://github.com/mlotfic/hijri-datetime#readme
10
+ Project-URL: Repository, https://github.com/mlotfic/hijri-datetime.git
11
+ Project-URL: Bug Tracker, https://github.com/mlotfic/hijri-datetime/issues
12
+ Project-URL: Changelog, https://github.com/mlotfic/hijri-datetime/blob/main/CHANGELOG.md
13
+ Project-URL: Source Code, https://github.com/mlotfic/hijri-datetime
14
+ Project-URL: Download, https://pypi.org/project/hijri-datetime/
15
+ Keywords: python,package,modules,portable,hijri,islamic,calendar,datetime,gregorian,jalali,conversion
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
10
18
  Classifier: Intended Audience :: Developers
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
11
21
  Classifier: Programming Language :: Python :: 3
12
22
  Classifier: Programming Language :: Python :: 3.8
13
23
  Classifier: Programming Language :: Python :: 3.9
@@ -15,14 +25,67 @@ Classifier: Programming Language :: Python :: 3.10
15
25
  Classifier: Programming Language :: Python :: 3.11
16
26
  Classifier: Programming Language :: Python :: 3.12
17
27
  Classifier: Operating System :: OS Independent
18
- Classifier: Topic :: Software Development :: Libraries
19
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
29
+ Classifier: Topic :: Software Development :: Internationalization
30
+ Classifier: Topic :: Utilities
20
31
  Requires-Python: >=3.8
21
32
  Description-Content-Type: text/markdown
22
33
  License-File: LICENSE
34
+ Requires-Dist: jdatetime>=3.0.0
35
+ Requires-Dist: requests>=2.20.0
36
+ Requires-Dist: numpy>=1.18.0
37
+ Requires-Dist: pandas>=1.0.0
38
+ Provides-Extra: all
39
+ Requires-Dist: pytest>=6.0; extra == "all"
40
+ Requires-Dist: pytest-cov>=2.0; extra == "all"
41
+ Requires-Dist: pytest-mock>=3.0; extra == "all"
42
+ Requires-Dist: black>=22.0; extra == "all"
43
+ Requires-Dist: flake8>=4.0; extra == "all"
44
+ Requires-Dist: mypy>=0.900; extra == "all"
45
+ Requires-Dist: isort>=5.0; extra == "all"
46
+ Requires-Dist: pre-commit>=2.0; extra == "all"
47
+ Requires-Dist: tox>=3.0; extra == "all"
48
+ Requires-Dist: build>=0.10; extra == "all"
49
+ Requires-Dist: twine>=4.0; extra == "all"
50
+ Requires-Dist: setuptools-scm>=6.2; extra == "all"
51
+ Requires-Dist: setuptools>=45; extra == "all"
52
+ Requires-Dist: wheel; extra == "all"
53
+ Requires-Dist: sphinx>=4.0; extra == "all"
54
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "all"
55
+ Requires-Dist: myst-parser>=0.17.0; extra == "all"
56
+ Provides-Extra: dev
57
+ Requires-Dist: pytest>=6.0; extra == "dev"
58
+ Requires-Dist: pytest-cov>=2.0; extra == "dev"
59
+ Requires-Dist: black>=22.0; extra == "dev"
60
+ Requires-Dist: flake8>=4.0; extra == "dev"
61
+ Requires-Dist: mypy>=0.900; extra == "dev"
62
+ Requires-Dist: pre-commit>=2.0; extra == "dev"
63
+ Requires-Dist: tox>=3.0; extra == "dev"
64
+ Requires-Dist: build>=0.10; extra == "dev"
65
+ Requires-Dist: twine>=4.0; extra == "dev"
66
+ Requires-Dist: setuptools-scm>=6.2; extra == "dev"
67
+ Requires-Dist: setuptools>=45; extra == "dev"
68
+ Requires-Dist: wheel; extra == "dev"
69
+ Requires-Dist: sphinx>=4.0; extra == "dev"
70
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "dev"
71
+ Provides-Extra: docs
72
+ Requires-Dist: sphinx>=4.0; extra == "docs"
73
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
74
+ Requires-Dist: myst-parser>=0.17.0; extra == "docs"
75
+ Provides-Extra: lint
76
+ Requires-Dist: black>=22.0; extra == "lint"
77
+ Requires-Dist: flake8>=4.0; extra == "lint"
78
+ Requires-Dist: mypy>=0.900; extra == "lint"
79
+ Requires-Dist: isort>=5.0; extra == "lint"
80
+ Provides-Extra: test
81
+ Requires-Dist: pytest>=6.0; extra == "test"
82
+ Requires-Dist: pytest-cov>=2.0; extra == "test"
83
+ Requires-Dist: pytest-mock>=3.0; extra == "test"
23
84
 
24
85
  # hijri-datetime
25
86
 
87
+ # 💡💡💡💡💡💡 **this not working yet** 💡💡💡💡
88
+
26
89
  📅 **Hijri (Islamic) calendar datetime library for Python**
27
90
  A drop-in replacement for Python's built-in `datetime` module, supporting Hijri date arithmetic, formatting, conversion, partial dates, and integration with `jdatetime`.
28
91
 
@@ -0,0 +1,17 @@
1
+ hijri_datetime/__init__.py,sha256=YnOnizT1unfEZn6tmi3Dus9VQggmNGYvVlMSv2VwySw,2033
2
+ hijri_datetime/_version.py,sha256=vqjwQ545ESEu9ocidQTg8luMMmtthTxpj1n-QHKjwpc,753
3
+ hijri_datetime/calendar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ hijri_datetime/constants.py,sha256=kLAJLq-QsULaHd_hz0QTpFLH93McQQFI2NeBEkLIHyg,1430
5
+ hijri_datetime/conversion.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ hijri_datetime/date.py,sha256=g6wRgHZzXUmiDWHp8bHJVcbyC5nqXFvMfU5IgWPE_cQ,4519
7
+ hijri_datetime/datetime.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ hijri_datetime/exceptions.py,sha256=TAiKzltQkFydMRv9vYfdrAStgoQ6ePe_evNoSkKNGr0,574
9
+ hijri_datetime/hello.py,sha256=PcWMF-H8OoHLsK4OW9QWYyMGnRsPz-hqLh916OLetPo,64
10
+ hijri_datetime/range.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ hijri_datetime/time.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ hijri_datetime/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ hijri_datetime-0.2.3.post0.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ hijri_datetime-0.2.3.post0.dist-info/METADATA,sha256=pTwgyBFZbrEOQgS1NJgVPB82mOTLkr2MADLbyWeZR_Y,8047
15
+ hijri_datetime-0.2.3.post0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
16
+ hijri_datetime-0.2.3.post0.dist-info/top_level.txt,sha256=3-byeAhSA03hoaPXanoyL76rRo5_FTCD9DIwk81fdck,15
17
+ hijri_datetime-0.2.3.post0.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- hijri_datetime/__init__.py,sha256=i2SM-vSV4sCVWyVki7bQpsJSEAw-RPLMMEXV3-MCWGM,57
2
- hijri_datetime/calendar.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- hijri_datetime/conversion.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- hijri_datetime/date.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- hijri_datetime/datetime.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- hijri_datetime/hello.py,sha256=PcWMF-H8OoHLsK4OW9QWYyMGnRsPz-hqLh916OLetPo,64
7
- hijri_datetime/range.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- hijri_datetime/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- hijri_datetime-0.1.1.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- hijri_datetime-0.1.1.dist-info/METADATA,sha256=ZO_RIIclicw70uUhHSCmHf5OAWdTUE0lGj4WEyc408c,4969
11
- hijri_datetime-0.1.1.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
12
- hijri_datetime-0.1.1.dist-info/top_level.txt,sha256=3-byeAhSA03hoaPXanoyL76rRo5_FTCD9DIwk81fdck,15
13
- hijri_datetime-0.1.1.dist-info/RECORD,,