nepali 0.5.5__py3-none-any.whl → 1.2.0__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.
- nepali/__init__.py +1 -1
- nepali/char.py +102 -81
- nepali/constants.py +66 -0
- nepali/date_converter.py +334 -0
- nepali/datetime/__init__.py +13 -14
- nepali/datetime/_datetime.py +391 -402
- nepali/datetime/_formatter.py +325 -0
- nepali/datetime/_humanize.py +117 -132
- nepali/datetime/_nepalimonth.py +118 -0
- nepali/datetime/_nepaliweek.py +125 -0
- nepali/datetime/parser/__init__.py +4 -4
- nepali/datetime/parser/_parser.py +59 -50
- nepali/datetime/parser/validators.py +249 -159
- nepali/datetime/utils.py +38 -0
- nepali/exceptions.py +8 -3
- nepali/locations/__init__.py +3 -0
- nepali/locations/_data.py +4271 -0
- nepali/locations/_locations.py +38 -0
- nepali/locations/models.py +104 -0
- nepali/locations/utils.py +54 -0
- nepali/number/__init__.py +19 -0
- nepali/number/_nepalinumber.py +563 -0
- nepali/number/_number.py +53 -0
- nepali/number/utils.py +72 -0
- nepali/phone_number.py +183 -0
- nepali/templatetags/__init__.py +0 -0
- nepali/templatetags/nepalidatetime.py +194 -24
- nepali/templatetags/nepalinumber.py +97 -7
- nepali/tests/test_date_converter.py +148 -0
- nepali/tests/test_datetime.py +275 -29
- nepali/tests/test_humanize.py +78 -7
- nepali/tests/test_locations.py +154 -0
- nepali/tests/test_nepalimonth.py +152 -0
- nepali/tests/test_nepaliweek.py +154 -0
- nepali/tests/test_number.py +3152 -0
- nepali/tests/test_parser.py +82 -69
- nepali/tests/test_phone_number.py +254 -0
- nepali/tests/test_timezone.py +192 -0
- nepali/timezone.py +50 -7
- nepali/utils.py +9 -68
- nepali-1.2.0.dist-info/METADATA +476 -0
- nepali-1.2.0.dist-info/RECORD +46 -0
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info}/WHEEL +1 -1
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info/licenses}/LICENSE +1 -1
- {nepali-0.5.5.dist-info → nepali-1.2.0.dist-info}/top_level.txt +0 -0
- nepali/datetime/_converter.py +0 -394
- nepali/datetime/_formarter.py +0 -314
- nepali/datetime.py +0 -1169
- nepali/number.py +0 -51
- nepali-0.5.5.dist-info/METADATA +0 -220
- nepali-0.5.5.dist-info/RECORD +0 -27
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from functools import cached_property
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from nepali.constants import NEPALI_MONTHS_EN, NEPALI_MONTHS_NE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NepaliMonthMeta(type):
|
|
10
|
+
_cache: dict[int, nepalimonth] = {}
|
|
11
|
+
|
|
12
|
+
def __call__(cls, month: int | str, *args, **kwargs) -> nepalimonth:
|
|
13
|
+
"""
|
|
14
|
+
Parses the month data and manages the cache.
|
|
15
|
+
|
|
16
|
+
:param month: An integer or string representing the month.
|
|
17
|
+
:type month: Union[int, str]
|
|
18
|
+
:return: An instance of the nepalimonth class representing the given month.
|
|
19
|
+
:rtype: nepalimonth
|
|
20
|
+
:raises ValueError: If the given month is invalid.
|
|
21
|
+
"""
|
|
22
|
+
value: int | None = None
|
|
23
|
+
value = None
|
|
24
|
+
|
|
25
|
+
if isinstance(month, int):
|
|
26
|
+
value = int(month)
|
|
27
|
+
elif isinstance(month, str):
|
|
28
|
+
try:
|
|
29
|
+
value = cls._parse_str(month)
|
|
30
|
+
except ValueError:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
# checking if month is valid
|
|
34
|
+
if value is None or value < 1 or value > 12:
|
|
35
|
+
raise ValueError(f"Invalid month: {month}")
|
|
36
|
+
|
|
37
|
+
# checking cache
|
|
38
|
+
if value not in cls._cache:
|
|
39
|
+
cls._cache[value] = super(NepaliMonthMeta, cls).__call__(
|
|
40
|
+
value, *args, **kwargs
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return cls._cache[value]
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _parse_str(month: str) -> int:
|
|
47
|
+
"""
|
|
48
|
+
Parses str value of the month and returns int.
|
|
49
|
+
|
|
50
|
+
:param month: A string representing the month.
|
|
51
|
+
:type month: str
|
|
52
|
+
:return: An integer representing the month.
|
|
53
|
+
:rtype: int
|
|
54
|
+
:raises ValueError: If the given string does not represent a valid month.
|
|
55
|
+
"""
|
|
56
|
+
if month.isdigit():
|
|
57
|
+
return int(month)
|
|
58
|
+
|
|
59
|
+
month = month.capitalize()
|
|
60
|
+
month_names = NEPALI_MONTHS_EN + NEPALI_MONTHS_NE
|
|
61
|
+
try:
|
|
62
|
+
index = month_names.index(month)
|
|
63
|
+
except ValueError:
|
|
64
|
+
raise ValueError(f"Invalid month name: {month}")
|
|
65
|
+
|
|
66
|
+
return (index % 12) + 1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class nepalimonth(metaclass=NepaliMonthMeta):
|
|
70
|
+
"""
|
|
71
|
+
Represents Nepali month: Baishakh, Jestha, ..., Chaitra.
|
|
72
|
+
Baishakh: 1,
|
|
73
|
+
Jestha: 2,
|
|
74
|
+
...
|
|
75
|
+
Chaitra: 12
|
|
76
|
+
|
|
77
|
+
>>> nepalimonth(1)
|
|
78
|
+
>>> nepalimonth("Baishakh")
|
|
79
|
+
>>> nepalimonth("बैशाख")
|
|
80
|
+
|
|
81
|
+
:param Union[int, str] month: Month data to be parsed.
|
|
82
|
+
|
|
83
|
+
:raises ValueError: The value is invalid.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(self, month) -> None:
|
|
87
|
+
self.__value = month
|
|
88
|
+
|
|
89
|
+
def __str__(self) -> str:
|
|
90
|
+
return self.name
|
|
91
|
+
|
|
92
|
+
def __repr__(self) -> str:
|
|
93
|
+
return f"<nepalimonth: {self.__value}>"
|
|
94
|
+
|
|
95
|
+
def __int__(self) -> int:
|
|
96
|
+
return self.value
|
|
97
|
+
|
|
98
|
+
def __eq__(self, other: Any) -> bool:
|
|
99
|
+
if isinstance(other, nepalimonth):
|
|
100
|
+
return self.value == other.value
|
|
101
|
+
elif isinstance(other, int):
|
|
102
|
+
return self.value == other
|
|
103
|
+
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
@cached_property
|
|
107
|
+
def value(self) -> int:
|
|
108
|
+
return self.__value
|
|
109
|
+
|
|
110
|
+
@cached_property
|
|
111
|
+
def name(self) -> str:
|
|
112
|
+
"""Month's english name"""
|
|
113
|
+
return NEPALI_MONTHS_EN[self.__value - 1]
|
|
114
|
+
|
|
115
|
+
@cached_property
|
|
116
|
+
def name_ne(self) -> str:
|
|
117
|
+
"""Month's nepali name"""
|
|
118
|
+
return NEPALI_MONTHS_NE[self.__value - 1]
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from functools import cached_property
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from nepali.constants import WEEKS_ABBR_EN, WEEKS_ABBR_NE, WEEKS_EN, WEEKS_NE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NepaliWeekMeta(type):
|
|
10
|
+
_cache: dict[int, nepaliweek] = {}
|
|
11
|
+
|
|
12
|
+
def __call__(cls, week: int | str, *args, **kwargs) -> nepaliweek:
|
|
13
|
+
"""
|
|
14
|
+
Parses the week data and manages the cache.
|
|
15
|
+
|
|
16
|
+
:param week: An integer or string representing the week.
|
|
17
|
+
:type week: Union[int, str]
|
|
18
|
+
:return: An instance of the nepaliweek class representing the given week.
|
|
19
|
+
:rtype: nepaliweek
|
|
20
|
+
:raises ValueError: If the given week is invalid.
|
|
21
|
+
"""
|
|
22
|
+
value: int | None = None
|
|
23
|
+
|
|
24
|
+
if isinstance(week, int):
|
|
25
|
+
value = int(week)
|
|
26
|
+
elif isinstance(week, str):
|
|
27
|
+
try:
|
|
28
|
+
value = cls._parse_str(week)
|
|
29
|
+
except ValueError:
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
# checking if week is valid
|
|
33
|
+
if value is None or not 0 <= value <= 6:
|
|
34
|
+
raise ValueError(f"Invalid week: {week}")
|
|
35
|
+
|
|
36
|
+
# checking cache
|
|
37
|
+
if value not in cls._cache:
|
|
38
|
+
cls._cache[value] = super().__call__(value, *args, **kwargs)
|
|
39
|
+
|
|
40
|
+
return cls._cache[value]
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def _parse_str(week: str) -> int:
|
|
44
|
+
"""
|
|
45
|
+
Parses str value of the week and returns int.
|
|
46
|
+
|
|
47
|
+
:param week: A string representing the week.
|
|
48
|
+
:type week: str
|
|
49
|
+
:return: An integer representing the week.
|
|
50
|
+
:rtype: int
|
|
51
|
+
:raises ValueError: If the given string does not represent a valid week.
|
|
52
|
+
"""
|
|
53
|
+
if week.isdigit():
|
|
54
|
+
return int(week)
|
|
55
|
+
|
|
56
|
+
week = week.capitalize()
|
|
57
|
+
week_names = WEEKS_EN + WEEKS_NE + WEEKS_ABBR_EN + WEEKS_ABBR_NE
|
|
58
|
+
try:
|
|
59
|
+
index = week_names.index(week)
|
|
60
|
+
except ValueError:
|
|
61
|
+
raise ValueError(f"Invalid week name: {week}")
|
|
62
|
+
|
|
63
|
+
return index % 7
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class nepaliweek(metaclass=NepaliWeekMeta):
|
|
67
|
+
"""
|
|
68
|
+
Represents Nepali week: Sunday, Monday, ..., Saturday.
|
|
69
|
+
Sunday: 0,
|
|
70
|
+
Monday: 1,
|
|
71
|
+
...
|
|
72
|
+
Saturday: 6
|
|
73
|
+
|
|
74
|
+
>>> nepaliweek(0)
|
|
75
|
+
>>> nepaliweek("Sunday")
|
|
76
|
+
>>> nepaliweek("आइतबार")
|
|
77
|
+
>>> nepaliweek("Sun")
|
|
78
|
+
|
|
79
|
+
:param Union[int, str] week: Week data to be parsed.
|
|
80
|
+
:raises ValueError: The value is invalid.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
def __init__(self, week) -> None:
|
|
84
|
+
self.__value = week
|
|
85
|
+
|
|
86
|
+
def __str__(self) -> str:
|
|
87
|
+
return self.name
|
|
88
|
+
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
return f"<nepaliweek: {self.__value}>"
|
|
91
|
+
|
|
92
|
+
def __int__(self) -> int:
|
|
93
|
+
return self.value
|
|
94
|
+
|
|
95
|
+
def __eq__(self, other: Any) -> bool:
|
|
96
|
+
if isinstance(other, nepaliweek):
|
|
97
|
+
return self.value == other.value
|
|
98
|
+
elif isinstance(other, int):
|
|
99
|
+
return self.value == other
|
|
100
|
+
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
@cached_property
|
|
104
|
+
def value(self) -> int:
|
|
105
|
+
return self.__value
|
|
106
|
+
|
|
107
|
+
@cached_property
|
|
108
|
+
def name(self) -> str:
|
|
109
|
+
"""Week's english name"""
|
|
110
|
+
return WEEKS_EN[self.__value]
|
|
111
|
+
|
|
112
|
+
@cached_property
|
|
113
|
+
def abbr(self) -> str:
|
|
114
|
+
"""Week's english abbreviated name"""
|
|
115
|
+
return WEEKS_ABBR_EN[self.__value]
|
|
116
|
+
|
|
117
|
+
@cached_property
|
|
118
|
+
def name_ne(self) -> str:
|
|
119
|
+
"""Week's nepali name"""
|
|
120
|
+
return WEEKS_NE[self.__value]
|
|
121
|
+
|
|
122
|
+
@cached_property
|
|
123
|
+
def abbr_ne(self) -> str:
|
|
124
|
+
"""Week's nepali abbreviated name"""
|
|
125
|
+
return WEEKS_ABBR_NE[self.__value]
|
|
@@ -1,65 +1,74 @@
|
|
|
1
|
-
from nepali.exceptions import
|
|
1
|
+
from nepali.exceptions import FormatNotMatchException, InvalidDateTimeFormatException
|
|
2
2
|
|
|
3
|
-
from.validators import validate
|
|
3
|
+
from .validators import validate
|
|
4
4
|
|
|
5
|
-
__all__ = [
|
|
5
|
+
__all__ = [
|
|
6
|
+
"strptime",
|
|
7
|
+
"parse",
|
|
8
|
+
]
|
|
6
9
|
|
|
7
10
|
_standard_datetime_format_CACHE = None
|
|
8
11
|
|
|
12
|
+
|
|
9
13
|
def strptime(datetime_str, format):
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
"""
|
|
15
|
+
Parses nepalidatetime str with the corresponding format.
|
|
16
|
+
returns nepalidatetime object.
|
|
17
|
+
"""
|
|
18
|
+
nepalidatetime_object = validate(datetime_str, format)
|
|
19
|
+
if nepalidatetime_object is None:
|
|
20
|
+
raise FormatNotMatchException(
|
|
21
|
+
"Datetime string did not match with the given format."
|
|
22
|
+
)
|
|
23
|
+
return nepalidatetime_object
|
|
24
|
+
|
|
18
25
|
|
|
19
26
|
def _get_standard_formats():
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
global _standard_datetime_format_CACHE
|
|
28
|
+
if _standard_datetime_format_CACHE is not None:
|
|
29
|
+
return _standard_datetime_format_CACHE
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
STANDARD_DATE_FORMAT = [
|
|
32
|
+
"%Y-%m-%d",
|
|
33
|
+
"%d-%m-%Y",
|
|
34
|
+
"%Y %m %d",
|
|
35
|
+
"%Y %B %d",
|
|
36
|
+
"%d %B %Y",
|
|
37
|
+
"%d %B, %Y",
|
|
38
|
+
"%B %d, %Y",
|
|
39
|
+
"%Y/%m/%d",
|
|
40
|
+
"%d/%m/%Y",
|
|
41
|
+
]
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
STANDARD_TIME_FORMAT = [
|
|
44
|
+
"%H:%M",
|
|
45
|
+
"%I:%M %p",
|
|
46
|
+
"%I %p",
|
|
47
|
+
"%I%p",
|
|
48
|
+
"%H:%M:%S",
|
|
49
|
+
"%H:%M:%S:%f",
|
|
50
|
+
]
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
_standard_datetime_format_CACHE = STANDARD_DATE_FORMAT.copy()
|
|
53
|
+
for time_format in STANDARD_TIME_FORMAT:
|
|
54
|
+
for date_format in STANDARD_DATE_FORMAT:
|
|
55
|
+
_standard_datetime_format_CACHE += [
|
|
56
|
+
f"{date_format} {time_format}",
|
|
57
|
+
f"{date_format}, {time_format}",
|
|
58
|
+
]
|
|
59
|
+
return _standard_datetime_format_CACHE
|
|
51
60
|
|
|
52
61
|
|
|
53
62
|
def parse(datetime_str):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
"""
|
|
64
|
+
parses nepali datetime
|
|
65
|
+
eg. parse('2078-10-12') => <NepaliDateTime: 2078-10-12>
|
|
66
|
+
"""
|
|
67
|
+
standard_formats = _get_standard_formats()
|
|
68
|
+
for format in standard_formats:
|
|
69
|
+
try:
|
|
70
|
+
return strptime(datetime_str, format=format)
|
|
71
|
+
except FormatNotMatchException:
|
|
72
|
+
pass
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
raise InvalidDateTimeFormatException("Invalid format to parse nepali datetime.")
|