Repository: sdispater/pendulum
Pull request #144 (2017-09-01 04:56:04)

fix wrong keyword argument 'dayss'
fix wrong keyword argument 'dayss'


Patch:
diff --git a/docs/_docs/difference.rst b/docs/_docs/difference.rst
index 9e56f01..53c8570 100644
--- a/docs/_docs/difference.rst
+++ b/docs/_docs/difference.rst
@@ -83,7 +83,7 @@ You may also pass ``True`` as a 2nd parameter to remove the modifiers `ago`, `fr
     # The most typical usage is for comments
     # The instance is the date the comment was created
     # and its being compared to default now()
-    pendulum.now().subtract(dayss=1).diff_for_humans()
+    pendulum.now().subtract(days=1).diff_for_humans()
     '5 days ago'
 
     pendulum.now().diff_for_humans(Pendulum.now().subtract(years=1))
diff --git a/pendulum/pendulum.py b/pendulum/pendulum.py
index 247112a..96ffd95 100644
--- a/pendulum/pendulum.py
+++ b/pendulum/pendulum.py
@@ -1769,7 +1769,8 @@ class Pendulum(Date, datetime.datetime):
         if dt is None:
             dt = Pendulum.now(self._tz)
 
-        return self.add(seconds=int(self.diff(dt, False).in_seconds() / 2))
+        diff = self.diff(dt, False)
+        return self.add(microseconds=(diff.in_seconds() * 1000000 + diff.microseconds) // 2)
 
     def _get_datetime(self, value, pendulum=False):
         """


Test patch:
diff --git a/tests/pendulum_tests/test_start_end_of.py b/tests/pendulum_tests/test_start_end_of.py
index fbc034c..f3ff332 100644
--- a/tests/pendulum_tests/test_start_end_of.py
+++ b/tests/pendulum_tests/test_start_end_of.py
@@ -1,7 +1,8 @@
 # -*- coding: utf-8 -*-
 
-from pendulum import Pendulum
+from itertools import product, tee
 
+from pendulum import Pendulum
 from .. import AbstractTestCase
 
 
@@ -208,19 +209,70 @@ class StartEndOfTest(AbstractTestCase):
         self.assertIsInstanceOfPendulum(d)
 
     def test_average_from_same(self):
-        d1 = Pendulum.create(2000, 1, 31, 2, 3, 4)
-        d2 = Pendulum.create(2000, 1, 31, 2, 3, 4).average(d1)
-        self.assertPendulum(d2, 2000, 1, 31, 2, 3, 4)
+        d1 = Pendulum.create(2000, 1, 31, 2, 3, 4, 5)
+        d2 = Pendulum.create(2000, 1, 31, 2, 3, 4, 5).average(d1)
+        self.assertPendulum(d2, 2000, 1, 31, 2, 3, 4, 5)
 
     def test_average_from_greater(self):
-        d1 = Pendulum.create(2000, 1, 1, 1, 1, 1, tz='local')
-        d2 = Pendulum.create(2009, 12, 31, 23, 59, 59, tz='local').average(d1)
-        self.assertPendulum(d2, 2004, 12, 31, 12, 30, 30)
+        d1 = Pendulum.create(2000, 1, 1, 1, 1, 1, 1, tz='local')
+        d2 = Pendulum.create(2009, 12, 31, 23, 59, 59, 999999, tz='local').average(d1)
+        self.assertPendulum(d2, 2004, 12, 31, 12, 30, 30, 500000)
 
     def test_average_from_lower(self):
-        d1 = Pendulum.create(2009, 12, 31, 23, 59, 59, tz='local')
-        d2 = Pendulum.create(2000, 1, 1, 1, 1, 1, tz='local').average(d1)
-        self.assertPendulum(d2, 2004, 12, 31, 12, 30, 30)
+        d1 = Pendulum.create(2009, 12, 31, 23, 59, 59, 999999, tz='local')
+        d2 = Pendulum.create(2000, 1, 1, 1, 1, 1, 1, tz='local').average(d1)
+        self.assertPendulum(d2, 2004, 12, 31, 12, 30, 30, 500000)
+
+    def test_average_with_microseconds(self):
+        for d1, d2, expected_average in [
+            # 3ms and 5ms should average to 4
+            ((1982, 12, 4, 17, 13, 0, 3), (1982, 12, 4, 17, 13, 0, 5), (1982, 12, 4, 17, 13, 0, 4)),
+            # 999999ms and subsequent 1ms should average to 0
+            ((1982, 12, 4, 0, 0, 0, 999999), (1982, 12, 4, 0, 0, 1, 1), (1982, 12, 4, 0, 0, 1, 0)),
+            # 1.000002 should average to 0.500001
+            ((2000, 1, 1, 0, 0, 0, 0), (2000, 1, 1, 0, 0, 1, 2), (2000, 1, 1, 0, 0, 0, 500001)),
+        ]:
+            d1 = Pendulum.create(*d1)
+            d2 = Pendulum.create(*d2)
+            a1 = d1.average(d2)
+            a2 = d2.average(d1)
+            self.assertPendulum(a1, *expected_average)
+            self.assertPendulum(a2, *expected_average)
+
+    def test_average_commutative(self):
+        for d1, d2 in product(*tee([
+            Pendulum.create(1981, 10,  9,  1,  2,  3,  4),
+            Pendulum.create(1982, 12,  4,  5,  6,  7,  8),
+            Pendulum.create(2013,  4, 13,  9, 10, 11, 12),
+            Pendulum.create(1982,  9, 24, 13, 14, 15, 16),
+        ])):
+            a1 = d1.average(d2)
+            a2 = d2.average(d1)
+            self.assertEqual(a1, a2)
+
+    def test_bisect_creates_all_times(self):
+
+        def bisect(start, end):
+            # should generate, in order, all microseconds between start and end
+            mid = start.average(end)
+            if mid == start or mid == end:
+                return
+            for d in bisect(start, mid):
+                yield d
+            yield mid
+            for d in bisect(mid, end):
+                yield d
+
+        start = Pendulum.now()
+        end = start.add(microseconds=1000)
+        d_next = start.copy()
+        n_values = 0
+        for d in bisect(start, end):
+            n_values += 1
+            d_next = d_next.add(microseconds=1)
+            self.assertEqual(d, d_next)
+
+        self.assertEqual(n_values, 999)
 
     def start_of_with_invalid_unit(self):
         self.assertRaises(ValueError, Pendulum.now().start_of('invalid'))