From 9903baf9e03a7ce2416485e68ffda1f63109cc1a Mon Sep 17 00:00:00 2001 From: 5j9 <5j9@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:14:25 +0330 Subject: [PATCH] chore(jalai.py): cleanup the code * Remove unneeded global statements. * Remove unneeded intermediate variable declarations. * Do not call int on floor division result. This is not needed in Python 3. Floor division always returns an integer in Python 3. * Use augmented arithmetic assignments (%=, -=, etc.) when possible. * Add a test for conversion on leap gregorian years. I noticed that there are no tests for this particular situation. --- jdatetime/jalali.py | 55 +++++++++++++++++---------------------------- tests/test_jdate.py | 14 ++++++++++++ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/jdatetime/jalali.py b/jdatetime/jalali.py index 8cd36d0..e2c90ac 100644 --- a/jdatetime/jalali.py +++ b/jdatetime/jalali.py @@ -25,32 +25,30 @@ def __gregorianToJalali(self): g_m: gregorian month g_d: gregorian day """ - global g_days_in_month, j_days_in_month - gy = self.gyear - 1600 gm = self.gmonth - 1 - gd = self.gday - 1 - g_day_no = 365 * gy + (gy + 3) // 4 - (gy + 99) // 100 + (gy + 399) // 400 + j_day_no = ( + 365 * gy + (gy + 3) // 4 - (gy + 99) // 100 + + (gy + 399) // 400 + self.gday - 1 - 79 + ) for i in range(gm): - g_day_no += g_days_in_month[i] + j_day_no += g_days_in_month[i] if gm > 1 and ((gy % 4 == 0 and gy % 100 != 0) or (gy % 400 == 0)): # leap and after Feb - g_day_no += 1 - g_day_no += gd - - j_day_no = g_day_no - 79 + j_day_no += 1 j_np = j_day_no // 12053 j_day_no %= 12053 - jy = 979 + 33 * j_np + 4 * int(j_day_no // 1461) + jy = 979 + 33 * j_np + 4 * (j_day_no // 1461) j_day_no %= 1461 if j_day_no >= 366: - jy += (j_day_no - 1) // 365 - j_day_no = (j_day_no - 1) % 365 + j_day_no -= 1 + jy += j_day_no // 365 + j_day_no %= 365 for i in range(11): if not j_day_no >= j_days_in_month[i]: @@ -58,12 +56,9 @@ def __gregorianToJalali(self): break j_day_no -= j_days_in_month[i] - jm = i + 2 - jd = j_day_no + 1 - self.jyear = jy - self.jmonth = jm - self.jday = jd + self.jmonth = i + 2 + self.jday = j_day_no + 1 class JalaliToGregorian: @@ -80,41 +75,33 @@ def getGregorianList(self): return (self.gyear, self.gmonth, self.gday) def __jalaliToGregorian(self): - global g_days_in_month, j_days_in_month jy = self.jyear - 979 - jm = self.jmonth - 1 - jd = self.jday - 1 - - j_day_no = 365 * jy + int(jy // 33) * 8 + (jy % 33 + 3) // 4 - for i in range(jm): - j_day_no += j_days_in_month[i] - - j_day_no += jd - - g_day_no = j_day_no + 79 + g_day_no = 365 * jy + (jy // 33) * 8 + (jy % 33 + 3) // 4 + self.jday - 1 + 79 + for i in range(self.jmonth - 1): + g_day_no += j_days_in_month[i] - gy = 1600 + 400 * int(g_day_no // 146097) # 146097 = 365*400 + 400/4 - 400/100 + 400/400 - g_day_no = g_day_no % 146097 + gy = 1600 + 400 * (g_day_no // 146097) # 146097 = 365*400 + 400/4 - 400/100 + 400/400 + g_day_no %= 146097 leap = 1 if g_day_no >= 36525: # 36525 = 365*100 + 100/4 g_day_no -= 1 - gy += 100 * int(g_day_no // 36524) # 36524 = 365*100 + 100/4 - 100/100 - g_day_no = g_day_no % 36524 + gy += 100 * (g_day_no // 36524) # 36524 = 365*100 + 100/4 - 100/100 + g_day_no %= 36524 if g_day_no >= 365: g_day_no += 1 else: leap = 0 - gy += 4 * int(g_day_no // 1461) # 1461 = 365*4 + 4/4 + gy += 4 * (g_day_no // 1461) # 1461 = 365*4 + 4/4 g_day_no %= 1461 if g_day_no >= 366: leap = 0 g_day_no -= 1 gy += g_day_no // 365 - g_day_no = g_day_no % 365 + g_day_no %= 365 i = 0 while g_day_no >= g_days_in_month[i] + (i == 1 and leap): diff --git a/tests/test_jdate.py b/tests/test_jdate.py index 64289e0..c8c7d8b 100644 --- a/tests/test_jdate.py +++ b/tests/test_jdate.py @@ -62,6 +62,20 @@ def test_fromgregorian_accepts_locale_keyword_arg_when_int_passed(self): j_today = jdatetime.date.fromgregorian(day=15, month=7, year=2018, locale='nl_NL') self.assertEqual(j_today.locale, 'nl_NL') + def test_togregorian_leap(self): + self.assertEqual( + jdatetime.date(1402, 12, 9).togregorian(), + datetime.date(2024, 2, 28), + ) + self.assertEqual( + jdatetime.date(1402, 12, 10).togregorian(), + datetime.date(2024, 2, 29), + ) + self.assertEqual( + jdatetime.date(1402, 12, 11).togregorian(), + datetime.date(2024, 3, 1), + ) + def test_replace_keeps_the_locale_of_source_date(self): date = jdatetime.date(1397, 4, 22, locale='nl_NL') other_date = date.replace(day=20)