519: Add support for datetime math r=hgrecco
See #510 

- add _Quantity.to_timedelta()
- modify addition and subtraction with datetimes to convert _Quantity instances to timedeltas before performing the operation
- add tests
This commit is contained in:
bors[bot]
2017-06-05 23:40:41 +00:00
2 changed files with 44 additions and 3 deletions

View File

@@ -10,6 +10,7 @@
from __future__ import division, unicode_literals, print_function, absolute_import
import copy
import datetime
import math
import operator
import functools
@@ -654,13 +655,18 @@ class _Quantity(SharedRegistryObject):
return self.__class__(magnitude, units)
def __iadd__(self, other):
if not isinstance(self._magnitude, ndarray):
if isinstance(other, datetime.datetime):
return self.to_timedelta() + other
elif not isinstance(self._magnitude, ndarray):
return self._add_sub(other, operator.add)
else:
return self._iadd_sub(other, operator.iadd)
def __add__(self, other):
return self._add_sub(other, operator.add)
if isinstance(other, datetime.datetime):
return self.to_timedelta() + other
else:
return self._add_sub(other, operator.add)
__radd__ = __add__
@@ -674,7 +680,10 @@ class _Quantity(SharedRegistryObject):
return self._add_sub(other, operator.sub)
def __rsub__(self, other):
return -self._add_sub(other, operator.sub)
if isinstance(other, datetime.datetime):
return other - self.to_timedelta()
else:
return -self._add_sub(other, operator.sub)
@ireduce_dimensions
def _imul_div(self, other, magnitude_op, units_op=None):
@@ -1511,6 +1520,9 @@ class _Quantity(SharedRegistryObject):
is_ok = False
return is_ok
def to_timedelta(self):
return datetime.timedelta(microseconds=self.to('microseconds').magnitude)
def build_quantity_class(registry, force_ndarray=False):

View File

@@ -3,6 +3,7 @@
from __future__ import division, unicode_literals, print_function, absolute_import
import copy
import datetime
import math
import operator as op
import warnings
@@ -1205,3 +1206,31 @@ class TestDimensionReduction(QuantityTestCase):
ureg = UnitRegistry(auto_reduce_dimensions=False)
x = (10 * ureg.feet) / (3 * ureg.inches)
self.assertEqual(x.units, ureg.feet / ureg.inches)
class TestTimedelta(QuantityTestCase):
def test_add_sub(self):
d = datetime.datetime(year=1968, month=1, day=10, hour=3, minute=42, second=24)
after = d + 3 * self.ureg.second
self.assertEqual(d + datetime.timedelta(seconds=3), after)
after = 3 * self.ureg.second + d
self.assertEqual(d + datetime.timedelta(seconds=3), after)
after = d - 3 * self.ureg.second
self.assertEqual(d - datetime.timedelta(seconds=3), after)
with self.assertRaises(DimensionalityError):
3 * self.ureg.second - d
def test_iadd_isub(self):
d = datetime.datetime(year=1968, month=1, day=10, hour=3, minute=42, second=24)
after = copy.copy(d)
after += 3 * self.ureg.second
self.assertEqual(d + datetime.timedelta(seconds=3), after)
after = 3 * self.ureg.second
after += d
self.assertEqual(d + datetime.timedelta(seconds=3), after)
after = copy.copy(d)
after -= 3 * self.ureg.second
self.assertEqual(d - datetime.timedelta(seconds=3), after)
after = 3 * self.ureg.second
with self.assertRaises(DimensionalityError):
after -= d