- commit
- 125a4fbda06d0b6f3ca17f5a427cf98af43a9a3c
- parent
- e002791230c5a023287eb8414bbe54dab84dc889
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-08-31 14:09
add allow_months parameter
Diffstat
| M | README.md | 7 | +++---- |
| M | nominaldelta.py | 16 | +++++++++------- |
| M | test.py | 16 | ++++++++++++++++ |
3 files changed, 28 insertions, 11 deletions
diff --git a/README.md b/README.md
@@ -77,7 +77,7 @@ that and seconds are added last. 77 77 78 78 When adding to a `date`, seconds are ignored. 79 7980 -1 ### `NominalDelta.diff(a, b)`-1 80 ### `NominalDelta.diff(a, b, allow_months=True)` 81 81 82 82 Calculate the delta between two `date` or `datetime` objects. This will first 83 83 check how many months can be added without overshooting. Then it will check how @@ -85,11 +85,10 @@ many days can be added on top of the month. Last, the remaining difference in 85 85 seconds is calculated. This approach is called "top heavy" because it 86 86 prioritizes larger units over smaller ones. 87 8788 -1 If you prefer to get a difference in days or seconds, you can derive them from89 -1 the absolute differences:-1 88 Set `allow_months=False` if you only want to get days and seconds. If you only -1 89 want seconds, use the absolute difference instead: 90 90 91 91 ```python92 -1 delta = NominalDelta(days=dt1.toordinal() - dt2.toordinal())93 92 delta = NominalDelta(seconds=dt1.timestamp() - dt2.timestamp()) 94 93 ``` 95 94
diff --git a/nominaldelta.py b/nominaldelta.py
@@ -51,18 +51,20 @@ def binary_search(a, b, delta): 51 51 return lower * delta 52 52 53 5354 -1 def date_diff(a, b):-1 54 def date_diff(a, b, *, allow_months=True): 55 55 if a > b: 56 56 return -date_diff(b, a)57 -1 delta = binary_search(a, b, NominalDelta(months=1))-1 57 delta = NominalDelta() -1 58 if allow_months: -1 59 delta += binary_search(a, b, NominalDelta(months=1)) 58 60 days = b.toordinal() - (a + delta).toordinal() 59 61 return delta + NominalDelta(days=days) 60 62 61 6362 -1 def dt_diff(a, b):-1 64 def dt_diff(a, b, *, allow_months=True): 63 65 if a > b: 64 66 return -dt_diff(b, a)65 -1 delta = date_diff(a, b)-1 67 delta = date_diff(a, b, allow_months=allow_months) 66 68 seconds = b.timestamp() - (a + delta).timestamp() 67 69 if seconds < 0: 68 70 delta -= NominalDelta(days=1) @@ -155,9 +157,9 @@ class NominalDelta: 155 157 return (-self).__radd__(other) 156 158 157 159 @classmethod158 -1 def diff(cls: type[Self], a: date, b: date) -> Self:-1 160 def diff(cls: type[Self], a: date, b: date, *, allow_months: bool = True) -> Self: 159 161 if isinstance(a, datetime) and isinstance(b, datetime):160 -1 return dt_diff(a, b)-1 162 return dt_diff(a, b, allow_months=allow_months) 161 163 elif isinstance(a, date) and isinstance(b, date):162 -1 return date_diff(a, b)-1 164 return date_diff(a, b, allow_months=allow_months) 163 165 raise TypeError('Unsupported types')
diff --git a/test.py b/test.py
@@ -386,3 +386,19 @@ class DiffTests(unittest.TestCase): 386 386 ), 387 387 NominalDelta(months=-1, seconds=-1), 388 388 ) -1 389 -1 390 def test_diff_no_allow_months(self): -1 391 self.assertEqual( -1 392 NominalDelta.diff( -1 393 date(1970, 1, 15), date(1970, 2, 15), allow_months=False -1 394 ), -1 395 NominalDelta(days=31), -1 396 ) -1 397 self.assertEqual( -1 398 NominalDelta.diff( -1 399 datetime(2001, 1, 1), -1 400 datetime(2003, 9, 17, 20, 54, 47), -1 401 allow_months=False, -1 402 ), -1 403 NominalDelta(days=989, seconds=75287), -1 404 )