persiantools 3.0.0__tar.gz → 4.0.0__tar.gz

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.
Files changed (23) hide show
  1. {persiantools-3.0.0 → persiantools-4.0.0}/LICENSE +2 -2
  2. {persiantools-3.0.0/persiantools.egg-info → persiantools-4.0.0}/PKG-INFO +22 -26
  3. {persiantools-3.0.0 → persiantools-4.0.0}/README.md +17 -19
  4. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools/__init__.py +2 -2
  5. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools/digits.py +12 -6
  6. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools/jdatetime.py +62 -44
  7. {persiantools-3.0.0 → persiantools-4.0.0/persiantools.egg-info}/PKG-INFO +22 -26
  8. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools.egg-info/SOURCES.txt +7 -1
  9. persiantools-4.0.0/persiantools.egg-info/requires.txt +1 -0
  10. {persiantools-3.0.0 → persiantools-4.0.0}/setup.py +5 -4
  11. persiantools-4.0.0/tests/test_characters.py +35 -0
  12. persiantools-4.0.0/tests/test_digits.py +64 -0
  13. persiantools-4.0.0/tests/test_jalalidate.py +318 -0
  14. persiantools-4.0.0/tests/test_jalalidatetime.py +326 -0
  15. persiantools-4.0.0/tests/test_utils.py +22 -0
  16. {persiantools-3.0.0 → persiantools-4.0.0}/MANIFEST.in +0 -0
  17. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools/characters.py +0 -0
  18. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools/utils.py +0 -0
  19. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools.egg-info/dependency_links.txt +0 -0
  20. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools.egg-info/not-zip-safe +0 -0
  21. {persiantools-3.0.0 → persiantools-4.0.0}/persiantools.egg-info/top_level.txt +0 -0
  22. {persiantools-3.0.0 → persiantools-4.0.0}/pyproject.toml +0 -0
  23. {persiantools-3.0.0 → persiantools-4.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
- Copyright (c) 2016-2021 Majid Hajiloo
3
+ Copyright (c) 2016-2024 Majid Hajiloo
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,24 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: persiantools
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Jalali date and datetime with other tools
5
5
  Home-page: https://github.com/majiidd/persiantools
6
6
  Author: Majid Hajiloo
7
7
  Author-email: majid.hajiloo@gmail.com
8
8
  License: MIT
9
9
  Keywords: jalali shamsi persian digits characters converter jalalidate jalalidatetime date datetime jdate jdatetime farsi
10
- Platform: UNKNOWN
11
10
  Classifier: Intended Audience :: Developers
12
11
  Classifier: License :: OSI Approved :: MIT License
13
12
  Classifier: Natural Language :: Persian
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Programming Language :: Python
16
15
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.6
18
- Classifier: Programming Language :: Python :: 3.7
19
16
  Classifier: Programming Language :: Python :: 3.8
20
17
  Classifier: Programming Language :: Python :: 3.9
21
18
  Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
22
21
  Classifier: Programming Language :: Python :: Implementation :: CPython
23
22
  Classifier: Programming Language :: Python :: Implementation :: PyPy
24
23
  Classifier: Topic :: Software Development
@@ -26,9 +25,10 @@ Classifier: Topic :: Software Development :: Libraries
26
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
26
  Classifier: Topic :: Software Development :: Localization
28
27
  Classifier: Topic :: Utilities
29
- Requires-Python: >=3.6
28
+ Requires-Python: >=3.8
30
29
  Description-Content-Type: text/markdown
31
30
  License-File: LICENSE
31
+ Requires-Dist: pytz
32
32
 
33
33
  # PersianTools
34
34
 
@@ -39,27 +39,25 @@ License-File: LICENSE
39
39
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)
40
40
  [![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)
41
41
 
42
- - Jalali (Shamsi) date and datetime (based on python datetime's module)
43
-
44
- - Convert Jalali to Gregorian date/datetime and vice versa
45
- - Support comparison and arithmetic operators such as `+`, `-`, `==`, `>=`
46
- - Support timezone
47
-
48
- - Convert Arabic and Persian characters/digits to each other
49
- - Convert numbers to words
42
+ Provides Jalali (also known as Shamsi or Persian) dates and datetimes functionalities, among other tools.
43
+ - It converts between Jalali and Gregorian dates and datetimes (based on python datetime's module).
44
+ - It supports operators like `+`, `-`, `==`, and `>=`.
45
+ - It includes timezone support.
46
+ - It converts between Arabic and Persian characters/digits.
47
+ - It turns numbers into Persian words.
50
48
 
51
49
  ## Install Package
52
-
53
- ```{.sourceCode .bash}
50
+ You can install the package using pip with the following command:
51
+ ```bash
54
52
  python -m pip install persiantools
55
53
  ```
56
- Persiantools supports Python 3.6+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
54
+ Persiantools supports Python 3.8+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
57
55
 
58
56
  ## How to use
59
57
 
60
58
  ### Date
61
59
 
62
- ```{.sourceCode .python}
60
+ ```python
63
61
  >>> from persiantools.jdatetime import JalaliDate
64
62
  >>> import datetime
65
63
 
@@ -84,7 +82,7 @@ JalaliDate(1367, 2, 14, Chaharshanbeh)
84
82
 
85
83
  ### Datetime
86
84
 
87
- ```{.sourceCode .python}
85
+ ```python
88
86
  >>> from persiantools.jdatetime import JalaliDateTime
89
87
  >>> import datetime, pytz
90
88
 
@@ -108,7 +106,7 @@ JalaliDateTime(1395, 4, 17, 21, 23, 53, 474618, tzinfo=<UTC>)
108
106
 
109
107
  Based on python `strftime()` behavior
110
108
 
111
- ```{.sourceCode .python}
109
+ ```python
112
110
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
113
111
  >>> import pytz
114
112
 
@@ -127,7 +125,7 @@ Based on python `strftime()` behavior
127
125
 
128
126
  ### Digits/Characters Tools
129
127
 
130
- ```{.sourceCode .python}
128
+ ```python
131
129
  >>> from persiantools import characters, digits
132
130
 
133
131
  >>> digits.en_to_fa("0987654321")
@@ -150,15 +148,15 @@ Based on python `strftime()` behavior
150
148
  ```
151
149
 
152
150
  ### Operators
153
-
154
- ```{.sourceCode .python}
151
+ The package supports various operators for date and time manipulations. Here are some examples:
152
+ ```python
155
153
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
156
154
  >>> import datetime
157
155
 
158
156
  >>> JalaliDate(1367, 2, 14) == JalaliDate(datetime.date(1988, 5, 4))
159
157
  True
160
158
 
161
- >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1369, 7, 1, 1, 0)
159
+ >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1368, 2, 14, 1, 0)
162
160
  False
163
161
 
164
162
  >>> JalaliDate(1367, 2, 14) == datetime.date(1988, 5, 4)
@@ -173,7 +171,7 @@ datetime.timedelta(365)
173
171
 
174
172
  ### Serializing and de-serializing
175
173
 
176
- ```{.sourceCode .python}
174
+ ```python
177
175
  >>> from persiantools.jdatetime import JalaliDate
178
176
  >>> import pickle
179
177
 
@@ -189,5 +187,3 @@ datetime.timedelta(365)
189
187
  >>> jalali
190
188
  JalaliDate(1367, 2, 14, Chaharshanbeh)
191
189
  ```
192
-
193
-
@@ -7,27 +7,25 @@
7
7
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)
8
8
  [![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)
9
9
 
10
- - Jalali (Shamsi) date and datetime (based on python datetime's module)
11
-
12
- - Convert Jalali to Gregorian date/datetime and vice versa
13
- - Support comparison and arithmetic operators such as `+`, `-`, `==`, `>=`
14
- - Support timezone
15
-
16
- - Convert Arabic and Persian characters/digits to each other
17
- - Convert numbers to words
10
+ Provides Jalali (also known as Shamsi or Persian) dates and datetimes functionalities, among other tools.
11
+ - It converts between Jalali and Gregorian dates and datetimes (based on python datetime's module).
12
+ - It supports operators like `+`, `-`, `==`, and `>=`.
13
+ - It includes timezone support.
14
+ - It converts between Arabic and Persian characters/digits.
15
+ - It turns numbers into Persian words.
18
16
 
19
17
  ## Install Package
20
-
21
- ```{.sourceCode .bash}
18
+ You can install the package using pip with the following command:
19
+ ```bash
22
20
  python -m pip install persiantools
23
21
  ```
24
- Persiantools supports Python 3.6+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
22
+ Persiantools supports Python 3.8+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
25
23
 
26
24
  ## How to use
27
25
 
28
26
  ### Date
29
27
 
30
- ```{.sourceCode .python}
28
+ ```python
31
29
  >>> from persiantools.jdatetime import JalaliDate
32
30
  >>> import datetime
33
31
 
@@ -52,7 +50,7 @@ JalaliDate(1367, 2, 14, Chaharshanbeh)
52
50
 
53
51
  ### Datetime
54
52
 
55
- ```{.sourceCode .python}
53
+ ```python
56
54
  >>> from persiantools.jdatetime import JalaliDateTime
57
55
  >>> import datetime, pytz
58
56
 
@@ -76,7 +74,7 @@ JalaliDateTime(1395, 4, 17, 21, 23, 53, 474618, tzinfo=<UTC>)
76
74
 
77
75
  Based on python `strftime()` behavior
78
76
 
79
- ```{.sourceCode .python}
77
+ ```python
80
78
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
81
79
  >>> import pytz
82
80
 
@@ -95,7 +93,7 @@ Based on python `strftime()` behavior
95
93
 
96
94
  ### Digits/Characters Tools
97
95
 
98
- ```{.sourceCode .python}
96
+ ```python
99
97
  >>> from persiantools import characters, digits
100
98
 
101
99
  >>> digits.en_to_fa("0987654321")
@@ -118,15 +116,15 @@ Based on python `strftime()` behavior
118
116
  ```
119
117
 
120
118
  ### Operators
121
-
122
- ```{.sourceCode .python}
119
+ The package supports various operators for date and time manipulations. Here are some examples:
120
+ ```python
123
121
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
124
122
  >>> import datetime
125
123
 
126
124
  >>> JalaliDate(1367, 2, 14) == JalaliDate(datetime.date(1988, 5, 4))
127
125
  True
128
126
 
129
- >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1369, 7, 1, 1, 0)
127
+ >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1368, 2, 14, 1, 0)
130
128
  False
131
129
 
132
130
  >>> JalaliDate(1367, 2, 14) == datetime.date(1988, 5, 4)
@@ -141,7 +139,7 @@ datetime.timedelta(365)
141
139
 
142
140
  ### Serializing and de-serializing
143
141
 
144
- ```{.sourceCode .python}
142
+ ```python
145
143
  >>> from persiantools.jdatetime import JalaliDate
146
144
  >>> import pickle
147
145
 
@@ -7,9 +7,9 @@
7
7
 
8
8
  __title__ = "persiantools"
9
9
  __url__ = "https://github.com/majiidd/persiantools"
10
- __version__ = "3.0.0"
10
+ __version__ = "4.0.0"
11
11
  __build__ = __version__
12
12
  __author__ = "Majid Hajiloo"
13
13
  __author_email__ = "majid.hajiloo@gmail.com"
14
14
  __license__ = "MIT"
15
- __copyright__ = "Copyright (c) 2016-2022 Majid Hajiloo"
15
+ __copyright__ = "Copyright (c) 2016-2024 Majid Hajiloo"
@@ -1,4 +1,4 @@
1
- from persiantools import utils
1
+ import re
2
2
 
3
3
  EN_TO_FA_MAP = {
4
4
  "0": "۰",
@@ -48,6 +48,12 @@ FA_TO_AR_MAP = {
48
48
  "۸": "٨",
49
49
  "۹": "٩",
50
50
  }
51
+
52
+ EN_TO_FA_REGEX = re.compile("|".join(EN_TO_FA_MAP.keys()))
53
+ AR_TO_FA_REGEX = re.compile("|".join(AR_TO_FA_MAP.keys()))
54
+ FA_TO_EN_REGEX = re.compile("|".join(FA_TO_EN_MAP.keys()))
55
+ FA_TO_AR_REGEX = re.compile("|".join(FA_TO_AR_MAP.keys()))
56
+
51
57
  ONES = ("یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه")
52
58
  TENS = ("بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود")
53
59
  HUNDREDS = ("یکصد", "دویست", "سیصد", "چهارصد", "پانصد", "ششصد", "هفتصد", "هشتصد", "نهصد")
@@ -80,7 +86,7 @@ DECISION = {
80
86
  1000: lambda n, depth: HUNDREDS[n // 100 - 1] + _to_word(n % 100, True),
81
87
  1000000: lambda n, depth: _to_word(n // 1000, depth) + BIG_RANGE[0] + _to_word(n % 1000, True),
82
88
  1000000000: lambda n, depth: _to_word(n // 1000000, depth) + BIG_RANGE[1] + _to_word(n % 1000000, True),
83
- 1000000000000: lambda n, depth: _to_word(n // n, depth) + BIG_RANGE[2] + _to_word(n % 1000000000, True),
89
+ 1000000000000: lambda n, depth: _to_word(n // 1000000000, depth) + BIG_RANGE[2] + _to_word(n % 1000000000, True),
84
90
  1000000000000000: lambda n, depth: _to_word(n // 1000000000000, depth)
85
91
  + BIG_RANGE[3]
86
92
  + _to_word(n % 1000000000000, True),
@@ -101,7 +107,7 @@ def en_to_fa(string: str) -> str:
101
107
  :param string: A string, will be converted
102
108
  :rtype: str
103
109
  """
104
- return utils.replace(string, EN_TO_FA_MAP)
110
+ return EN_TO_FA_REGEX.sub(lambda x: EN_TO_FA_MAP[x.group()], string)
105
111
 
106
112
 
107
113
  def ar_to_fa(string: str) -> str:
@@ -114,7 +120,7 @@ def ar_to_fa(string: str) -> str:
114
120
  :param string: A string, will be converted
115
121
  :rtype: str
116
122
  """
117
- return utils.replace(string, AR_TO_FA_MAP)
123
+ return AR_TO_FA_REGEX.sub(lambda x: AR_TO_FA_MAP[x.group()], string)
118
124
 
119
125
 
120
126
  def fa_to_en(string: str) -> str:
@@ -127,7 +133,7 @@ def fa_to_en(string: str) -> str:
127
133
  :param string: A string, will be converted
128
134
  :rtype: str
129
135
  """
130
- return utils.replace(string, FA_TO_EN_MAP)
136
+ return FA_TO_EN_REGEX.sub(lambda x: FA_TO_EN_MAP[x.group()], string)
131
137
 
132
138
 
133
139
  def fa_to_ar(string: str) -> str:
@@ -140,7 +146,7 @@ def fa_to_ar(string: str) -> str:
140
146
  :param string: A string, will be converted
141
147
  :rtype: str
142
148
  """
143
- return utils.replace(string, FA_TO_AR_MAP)
149
+ return FA_TO_AR_REGEX.sub(lambda x: FA_TO_AR_MAP[x.group()], string)
144
150
 
145
151
 
146
152
  def _to_word(number: int, depth: bool) -> str:
@@ -181,7 +181,7 @@ class JalaliDate:
181
181
  return year, month, day, locale
182
182
 
183
183
  @classmethod
184
- def chack_date(cls, year, month, day):
184
+ def check_date(cls, year, month, day):
185
185
  try:
186
186
  cls._check_date_fields(year, month, day, "en")
187
187
  except (ValueError, TypeError):
@@ -191,11 +191,19 @@ class JalaliDate:
191
191
 
192
192
  @staticmethod
193
193
  def is_leap(year):
194
- assert MINYEAR <= year <= MAXYEAR
194
+ """
195
+ This function calculates whether a given year in the Persian calendar is a leap year.
195
196
 
196
- c = 0.24219858156028368 # 683 / 2820
197
- # return ((year + 2346) * 683) % 2820 < 683
198
- return ((year + 2346) * c) % 1 < c
197
+ It calculates `((year + 2346) * 683) % 2820`. This expression does a few things:
198
+ - It offsets the input year by 2346. This is done to align the Persian calendar with the astronomical solar year.
199
+ - It multiplies the result by 683, which is the number of leap years in a 2820-year cycle.
200
+ - It then takes the result modulo 2820 to get the position of the year within the current 2820-year cycle.
201
+
202
+ If the result of this calculation is less than 683, the year is a leap year in the Persian calendar.
203
+ This is because there are 683 leap years in each 2820-year cycle of the Persian calendar.
204
+ """
205
+ assert MINYEAR <= year <= MAXYEAR
206
+ return ((year + 2346) * 683) % 2820 < 683
199
207
 
200
208
  @classmethod
201
209
  def days_in_month(cls, month, year):
@@ -220,31 +228,40 @@ class JalaliDate:
220
228
  day = year.day
221
229
  year = year.year
222
230
 
223
- g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
231
+ # Days in each month of the Gregorian calendar
232
+ gregorian_days_in_month = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
224
233
 
225
- jy = 0 if year <= 1600 else 979
234
+ # Determine the Jalali year
235
+ jalali_year = 0 if year <= 1600 else 979
226
236
  year -= 621 if year <= 1600 else 1600
227
- year2 = year + 1 if month > 2 else year
228
- days = (365 * year) + int((year2 + 3) / 4) - int((year2 + 99) / 100)
229
- days += int((year2 + 399) / 400) - 80 + day + g_d_m[month - 1]
230
- jy += 33 * int(days / 12053)
237
+
238
+ # Determine if the year is a leap year
239
+ leap_year = year + 1 if month > 2 else year
240
+
241
+ # Calculate the number of days
242
+ days = (365 * year) + (leap_year + 3) // 4 - (leap_year + 99) // 100
243
+ days += (leap_year + 399) // 400 - 80 + day + gregorian_days_in_month[month - 1]
244
+
245
+ # Update the Jalali year
246
+ jalali_year += 33 * (days // 12053)
231
247
  days %= 12053
232
- jy += 4 * int(days / 1461)
248
+ jalali_year += 4 * (days // 1461)
233
249
  days %= 1461
234
- jy += int((days - 1) / 365)
250
+ jalali_year += (days - 1) // 365
235
251
 
236
252
  if days > 365:
237
253
  days = (days - 1) % 365
238
254
 
255
+ # Determine the Jalali month and day
239
256
  if days < 186:
240
- jm = 1 + int(days / 31)
241
- jd = 1 + (days % 31)
257
+ jalali_month = 1 + days // 31
258
+ jalali_day = 1 + (days % 31)
242
259
  else:
243
- arit = days - 186
244
- jm = 7 + int(arit / 30)
245
- jd = 1 + (arit % 30)
260
+ days -= 186
261
+ jalali_month = 7 + days // 30
262
+ jalali_day = 1 + (days % 30)
246
263
 
247
- return cls(jy, jm, jd)
264
+ return cls(jalali_year, jalali_month, jalali_day)
248
265
 
249
266
  def to_gregorian(self):
250
267
  """based on jdf.scr.ir"""
@@ -252,37 +269,40 @@ class JalaliDate:
252
269
  day = self.day
253
270
  year = self.year
254
271
 
255
- gy = 621 if year <= 979 else 1600
272
+ # Determine the Gregorian year
273
+ gregorian_year = 621 if year <= 979 else 1600
256
274
  year -= 0 if year <= 979 else 979
257
275
 
258
- d = (month - 1) * 31 if month < 7 else ((month - 7) * 30) + 186
259
- days = (365 * year) + (int(year / 33) * 8) + int(((year % 33) + 3) / 4)
260
- days += 78 + day + d
276
+ # Calculate the number of days
277
+ days_in_month = (month - 1) * 31 if month < 7 else ((month - 7) * 30) + 186
278
+ days = (365 * year) + (year // 33) * 8 + ((year % 33) + 3) // 4
279
+ days += 78 + day + days_in_month
261
280
 
262
- gy += 400 * int(days / 146097)
281
+ gregorian_year += 400 * (days // 146097)
263
282
  days %= 146097
264
283
 
265
284
  if days > 36524:
266
285
  days -= 1
267
- gy += 100 * int(days / 36524)
286
+ gregorian_year += 100 * (days // 36524)
268
287
  days %= 36524
269
288
 
270
289
  if days >= 365:
271
290
  days += 1
272
291
 
273
- gy += 4 * int(days / 1461)
292
+ gregorian_year += 4 * (days // 1461)
274
293
  days %= 1461
275
- gy += int((days - 1) / 365)
294
+ gregorian_year += (days - 1) // 365
276
295
 
277
296
  if days > 365:
278
297
  days = (days - 1) % 365
279
298
 
280
- gd = days + 1
299
+ gregorian_day = days + 1
281
300
 
282
- g_d_m = [
301
+ # Days in each month of the Gregorian calendar
302
+ gregorian_days_in_month = [
283
303
  0,
284
304
  31,
285
- 29 if (gy % 4 == 0 and gy % 100 != 0) or gy % 400 == 0 else 28,
305
+ 29 if (gregorian_year % 4 == 0 and gregorian_year % 100 != 0) or gregorian_year % 400 == 0 else 28,
286
306
  31,
287
307
  30,
288
308
  31,
@@ -295,13 +315,13 @@ class JalaliDate:
295
315
  31,
296
316
  ]
297
317
 
298
- _gm = 0
299
- for _gm, g in enumerate(g_d_m):
300
- if gd <= g:
318
+ # Determine the Gregorian month
319
+ for _gregorian_month, g in enumerate(gregorian_days_in_month):
320
+ if gregorian_day <= g:
301
321
  break
302
- gd -= g
322
+ gregorian_day -= g
303
323
 
304
- return date(gy, _gm, gd)
324
+ return date(gregorian_year, _gregorian_month, gregorian_day)
305
325
 
306
326
  @classmethod
307
327
  def today(cls):
@@ -958,7 +978,7 @@ class JalaliDateTime(JalaliDate):
958
978
  "%B": cls.__seqToRE(cls, month_names, "B"),
959
979
  "%H": r"(?P<H>2[0-3]|[0-1]\d|\d)",
960
980
  "%I": r"(?P<I>1[0-2]|0[1-9]|[1-9])",
961
- "%p": "(?i)" + cls.__seqToRE(cls, periods, "p"),
981
+ "%p": cls.__seqToRE(cls, periods, "p"),
962
982
  "%M": r"(?P<M>[0-5]\d|\d)",
963
983
  "%S": r"(?P<S>6[0-1]|[0-5]\d|\d)",
964
984
  "%f": r"(?P<f>\d{1,6})",
@@ -977,8 +997,8 @@ class JalaliDateTime(JalaliDate):
977
997
 
978
998
  data_string_regex = utils.replace(fmt, directives_regex_pattern)
979
999
 
980
- if re.match(data_string_regex, data_string):
981
- directives = re.search(data_string_regex, data_string).groupdict()
1000
+ if re.match(data_string_regex, data_string, re.IGNORECASE):
1001
+ directives = re.search(data_string_regex, data_string, re.IGNORECASE).groupdict()
982
1002
 
983
1003
  if "Y" in directives.keys() and len(directives.get("Y")) < 4:
984
1004
  raise ValueError("Year element must contain exactly 4 digits")
@@ -1100,7 +1120,7 @@ class JalaliDateTime(JalaliDate):
1100
1120
  def __base_compare(self, other):
1101
1121
  assert isinstance(other, JalaliDateTime)
1102
1122
 
1103
- y, m, d, h, m, s, ms = [
1123
+ y, mo, d, h, m, s, ms = [
1104
1124
  self._year,
1105
1125
  self._month,
1106
1126
  self._day,
@@ -1109,7 +1129,7 @@ class JalaliDateTime(JalaliDate):
1109
1129
  self._second,
1110
1130
  self._microsecond,
1111
1131
  ]
1112
- y2, m2, d2, h2, m2, s2, ms2 = [
1132
+ y2, mo2, d2, h2, m2, s2, ms2 = [
1113
1133
  other.year,
1114
1134
  other.month,
1115
1135
  other.day,
@@ -1121,10 +1141,8 @@ class JalaliDateTime(JalaliDate):
1121
1141
 
1122
1142
  return (
1123
1143
  0
1124
- if (y, m, d, h, m, s, ms) == (y2, m2, d2, h2, m2, s2, ms2)
1125
- else 1
1126
- if (y, m, d, h, m, s, ms) > (y2, m2, d2, h2, m2, s2, ms2)
1127
- else -1
1144
+ if (y, mo, d, h, m, s, ms) == (y2, mo2, d2, h2, m2, s2, ms2)
1145
+ else 1 if (y, mo, d, h, m, s, ms) > (y2, mo2, d2, h2, m2, s2, ms2) else -1
1128
1146
  )
1129
1147
 
1130
1148
  def _cmp(self, other, allow_mixed=False):
@@ -1,24 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: persiantools
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Jalali date and datetime with other tools
5
5
  Home-page: https://github.com/majiidd/persiantools
6
6
  Author: Majid Hajiloo
7
7
  Author-email: majid.hajiloo@gmail.com
8
8
  License: MIT
9
9
  Keywords: jalali shamsi persian digits characters converter jalalidate jalalidatetime date datetime jdate jdatetime farsi
10
- Platform: UNKNOWN
11
10
  Classifier: Intended Audience :: Developers
12
11
  Classifier: License :: OSI Approved :: MIT License
13
12
  Classifier: Natural Language :: Persian
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Programming Language :: Python
16
15
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.6
18
- Classifier: Programming Language :: Python :: 3.7
19
16
  Classifier: Programming Language :: Python :: 3.8
20
17
  Classifier: Programming Language :: Python :: 3.9
21
18
  Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
22
21
  Classifier: Programming Language :: Python :: Implementation :: CPython
23
22
  Classifier: Programming Language :: Python :: Implementation :: PyPy
24
23
  Classifier: Topic :: Software Development
@@ -26,9 +25,10 @@ Classifier: Topic :: Software Development :: Libraries
26
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
26
  Classifier: Topic :: Software Development :: Localization
28
27
  Classifier: Topic :: Utilities
29
- Requires-Python: >=3.6
28
+ Requires-Python: >=3.8
30
29
  Description-Content-Type: text/markdown
31
30
  License-File: LICENSE
31
+ Requires-Dist: pytz
32
32
 
33
33
  # PersianTools
34
34
 
@@ -39,27 +39,25 @@ License-File: LICENSE
39
39
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)
40
40
  [![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)
41
41
 
42
- - Jalali (Shamsi) date and datetime (based on python datetime's module)
43
-
44
- - Convert Jalali to Gregorian date/datetime and vice versa
45
- - Support comparison and arithmetic operators such as `+`, `-`, `==`, `>=`
46
- - Support timezone
47
-
48
- - Convert Arabic and Persian characters/digits to each other
49
- - Convert numbers to words
42
+ Provides Jalali (also known as Shamsi or Persian) dates and datetimes functionalities, among other tools.
43
+ - It converts between Jalali and Gregorian dates and datetimes (based on python datetime's module).
44
+ - It supports operators like `+`, `-`, `==`, and `>=`.
45
+ - It includes timezone support.
46
+ - It converts between Arabic and Persian characters/digits.
47
+ - It turns numbers into Persian words.
50
48
 
51
49
  ## Install Package
52
-
53
- ```{.sourceCode .bash}
50
+ You can install the package using pip with the following command:
51
+ ```bash
54
52
  python -m pip install persiantools
55
53
  ```
56
- Persiantools supports Python 3.6+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
54
+ Persiantools supports Python 3.8+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
57
55
 
58
56
  ## How to use
59
57
 
60
58
  ### Date
61
59
 
62
- ```{.sourceCode .python}
60
+ ```python
63
61
  >>> from persiantools.jdatetime import JalaliDate
64
62
  >>> import datetime
65
63
 
@@ -84,7 +82,7 @@ JalaliDate(1367, 2, 14, Chaharshanbeh)
84
82
 
85
83
  ### Datetime
86
84
 
87
- ```{.sourceCode .python}
85
+ ```python
88
86
  >>> from persiantools.jdatetime import JalaliDateTime
89
87
  >>> import datetime, pytz
90
88
 
@@ -108,7 +106,7 @@ JalaliDateTime(1395, 4, 17, 21, 23, 53, 474618, tzinfo=<UTC>)
108
106
 
109
107
  Based on python `strftime()` behavior
110
108
 
111
- ```{.sourceCode .python}
109
+ ```python
112
110
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
113
111
  >>> import pytz
114
112
 
@@ -127,7 +125,7 @@ Based on python `strftime()` behavior
127
125
 
128
126
  ### Digits/Characters Tools
129
127
 
130
- ```{.sourceCode .python}
128
+ ```python
131
129
  >>> from persiantools import characters, digits
132
130
 
133
131
  >>> digits.en_to_fa("0987654321")
@@ -150,15 +148,15 @@ Based on python `strftime()` behavior
150
148
  ```
151
149
 
152
150
  ### Operators
153
-
154
- ```{.sourceCode .python}
151
+ The package supports various operators for date and time manipulations. Here are some examples:
152
+ ```python
155
153
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
156
154
  >>> import datetime
157
155
 
158
156
  >>> JalaliDate(1367, 2, 14) == JalaliDate(datetime.date(1988, 5, 4))
159
157
  True
160
158
 
161
- >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1369, 7, 1, 1, 0)
159
+ >>> JalaliDateTime(1367, 2, 14, 4, 30) >= JalaliDateTime(1368, 2, 14, 1, 0)
162
160
  False
163
161
 
164
162
  >>> JalaliDate(1367, 2, 14) == datetime.date(1988, 5, 4)
@@ -173,7 +171,7 @@ datetime.timedelta(365)
173
171
 
174
172
  ### Serializing and de-serializing
175
173
 
176
- ```{.sourceCode .python}
174
+ ```python
177
175
  >>> from persiantools.jdatetime import JalaliDate
178
176
  >>> import pickle
179
177
 
@@ -189,5 +187,3 @@ datetime.timedelta(365)
189
187
  >>> jalali
190
188
  JalaliDate(1367, 2, 14, Chaharshanbeh)
191
189
  ```
192
-
193
-