Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(strptime):handle %b and %B directive. #121

Merged
merged 5 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 37 additions & 9 deletions jdatetime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,18 @@ def fromordinal(ordinal):
(y, m, d) = GregorianToJalali(d.year, d.month, d.day).getJalaliList()
return date(y, m, d)

@staticmethod
def j_month_to_num(month_name):
return date.j_months_en.index(month_name.lower().capitalize()) + 1

@staticmethod
def j_month_short_to_num(month_name):
return date.j_months_short_en.index(month_name.lower().capitalize()) + 1

@staticmethod
def j_month_fa_to_num(month_name):
return date.j_months_fa.index(month_name) + 1

def __repr__(self):
return f"jdatetime.date({self.year}, {self.month}, {self.day})"

Expand Down Expand Up @@ -636,14 +648,16 @@ def aslocale(self, locale):
date.max = date(MAXYEAR, 12, 30)

_DIRECTIVE_PATTERNS = {
'%Y': '(?P<Y>[0-9]{4})',
'%y': '(?P<y>[0-9]{2})',
'%m': '(?P<m>[0-9]{1,2})',
'%d': '(?P<d>[0-9]{1,2})',
'%H': '(?P<H>[0-9]{1,2})',
'%M': '(?P<M>[0-9]{1,2})',
'%S': '(?P<S>[0-9]{1,2})',
'%f': '(?P<f>[0-9]{1,6})',
'%Y': '(?P<Y>\d{4})',
'%y': '(?P<y>\d{2})',
'%m': '(?P<m>\d{1,2})',
'%d': '(?P<d>\d{1,2})',
'%H': '(?P<H>\d{1,2})',
'%M': '(?P<M>\d{1,2})',
'%S': '(?P<S>\d{1,2})',
'%f': '(?P<f>\d{1,6})',
'%B': '(?P<B>[a-zA-Z\u0600-\u06EF\uFB8A\u067E\u0686\u06AF]{3,12})',
'%b': '(?P<b>[a-zA-Z]{3})',
}


Expand Down Expand Up @@ -914,9 +928,23 @@ def strptime(date_string, format):
year = int(get('Y') or get('y') or 1279)
if year < 100: # %y, see the discussion at #100
year += 1400 if year <= 68 else 1300
month = get('B') or get('b') or int(get('m', 1))
if isinstance(month, str):
try:
if get('b'):
month = date.j_month_short_to_num(month_name=month)
elif month.isascii():
month = date.j_month_to_num(month_name=month)
else:
month = date.j_month_fa_to_num(month_name=month)
except ValueError:
raise ValueError(
"time data '%s' does not match format '%s'" %
(date_string, format)
)
return datetime(
year,
int(get('m', 1)),
month,
int(get('d', 1)),
int(get('H', 0)),
int(get('M', 0)),
Expand Down
37 changes: 37 additions & 0 deletions tests/test_jdatetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,43 @@ def test_strptime_nanoseconds(self):
jdatetime.datetime.strptime("0123", "%f")
)

def test_strptime_handle_b_B_directive(self):
tests = [
('14 Ordibehesht 1400', '%d %B %Y'),
('14 ordibehesht 1400', '%d %B %Y'),
('14 ordiBehesHt 1400', '%d %B %Y'),
('۱۴ Ordibehesht ۱۴۰۰', '%d %B %Y'),
('۱۴ ordibehesht ۱۴۰۰', '%d %B %Y'),
('۱۴ orDibeHesht ۱۴۰۰', '%d %B %Y'),
('1۴ Ordibehesht 14۰۰', '%d %B %Y'),
('۱4 ordibehesht 14۰0', '%d %B %Y'),
('۱4 OrdiBeheshT 14۰0', '%d %B %Y'),
('۱۴ اردیبهشت ۱۴۰۰', '%d %B %Y'),
('14 اردیبهشت 1400', '%d %B %Y'),
('1۴ اردیبهشت ۱4۰0', '%d %B %Y'),
('14 Ord 1400', '%d %b %Y'),
('14 ord 1400', '%d %b %Y'),
('14 oRD 1400', '%d %b %Y'),
('۱۴ Ord ۱۴۰۰', '%d %b %Y'),
('۱۴ ord ۱۴۰۰', '%d %b %Y'),
('۱۴ OrD ۱۴۰۰', '%d %b %Y'),
('۱4 Ord 14۰0', '%d %b %Y'),
('۱4 ord 14۰0', '%d %b %Y'),
('۱4 ORD 14۰0', '%d %b %Y'),
]
for date_string, date_format in tests:
with self.subTest(date_string=date_string, date_format=date_format):
date = jdatetime.datetime.strptime(date_string, date_format)
self.assertEqual(jdatetime.datetime(1400, 2, 14), date)

def test_strptime_invalid_date_string_b_directive(self):
with self.assertRaises(ValueError, msg="time data '14 DRO 1400' does not match format '%d %b %Y'"):
jdatetime.datetime.strptime('14 DRO 1400', '%d %b %Y')

def test_strptime_invalid_date_string_B_directive(self):
with self.assertRaises(ValueError, msg="time data '14 ordi 1400' does not match format '%d %B %Y'"):
jdatetime.datetime.strptime('14 ordi 1400', '%d %B %Y')

def test_datetime_eq(self):
date_string = "1363-6-6 12:13:14"
date_format = "%Y-%m-%d %H:%M:%S"
Expand Down