Преглед изворни кода

Fixed delta_resolution for days, hours and minutes.

Ask Solem пре 15 година
родитељ
комит
d76fbc957c
2 измењених фајлова са 41 додато и 8 уклоњено
  1. 30 8
      celery/task/base.py
  2. 11 0
      celery/tests/test_task.py

+ 30 - 8
celery/task/base.py

@@ -714,12 +714,34 @@ class PeriodicTask(Task):
         return False, rem
 
     def delta_resolution(self, dt, delta):
-        resolution = {3: lambda x: x / 86400,
-                      4: lambda x: x / 3600,
-                      5: lambda x: x / 60}
+        """Round a datetime to the resolution of a timedelta.
+
+        If the timedelta is in days, the datetime will be rounded
+        to the nearest days, if the timedelta is in hours the datetime
+        will be rounded to the nearest hour, and so on until seconds
+        which will just return the original datetime.
+
+            >>> now = datetime.now()
+            >>> now
+            datetime.datetime(2010, 3, 30, 11, 50, 58, 41065)
+            >>> delta_resolution(now, timedelta(days=2))
+            datetime.datetime(2010, 3, 30, 0, 0)
+            >>> delta_resolution(now, timedelta(hours=2))
+            datetime.datetime(2010, 3, 30, 11, 0)
+            >>> delta_resolution(now, timedelta(minutes=2))
+            datetime.datetime(2010, 3, 30, 11, 50)
+            >>> delta_resolution(now, timedelta(seconds=2))
+            datetime.datetime(2010, 3, 30, 11, 50, 58, 41065)
+
+        """
+        delta = self.timedelta_seconds(delta)
+
+        resolutions = ((3, lambda x: x / 86400),
+                       (4, lambda x: x / 3600),
+                       (5, lambda x: x / 60))
+
         args = dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second
-        r = None
-        for res, predicate in resolution.items():
-            if predicate(self.timedelta_seconds(delta)):
-                r = res
-        return datetime(*args[:r])
+        for res, predicate in resolutions:
+            if predicate(delta) >= 1.0:
+                return datetime(*args[:res])
+        return dt

+ 11 - 0
celery/tests/test_task.py

@@ -436,6 +436,17 @@ class TestPeriodicTask(unittest.TestCase):
         for delta, seconds in deltamap:
             self.assertEqual(MyPeriodic().timedelta_seconds(delta), seconds)
 
+    def test_delta_resolution(self):
+        D = MyPeriodic().delta_resolution
+
+        dt = datetime(2010, 3, 30, 11, 50, 58, 41065)
+        deltamap = ((timedelta(days=2), datetime(2010, 3, 30, 0, 0)),
+                    (timedelta(hours=2), datetime(2010, 3, 30, 11, 0)),
+                    (timedelta(minutes=2), datetime(2010, 3, 30, 11, 50)),
+                    (timedelta(seconds=2), dt))
+        for delta, shoulda in deltamap:
+            self.assertEqual(D(dt, delta), shoulda)
+
     def test_is_due_not_due(self):
         due, remaining = MyPeriodic().is_due(datetime.now())
         self.assertFalse(due)