Fix for floating point durations

The duration calculation was using %, but that's only supported on
duration objects when the arithmetic type supports %, and hence fails
for floats.  Fixed by subtracting off the calculated values instead.
This commit is contained in:
Jason Rhinelander 2017-03-11 22:29:25 -04:00
parent 28a837a07e
commit e5456c2226
3 changed files with 16 additions and 4 deletions

View File

@ -85,9 +85,11 @@ public:
using ss_t = duration<int, std::ratio<1>>;
using us_t = duration<int, std::micro>;
return PyDelta_FromDSU(duration_cast<dd_t>(d).count(),
duration_cast<ss_t>(d % days(1)).count(),
duration_cast<us_t>(d % seconds(1)).count());
auto dd = duration_cast<dd_t>(d);
auto subd = d - dd;
auto ss = duration_cast<ss_t>(subd);
auto us = duration_cast<us_t>(subd - ss);
return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
}
PYBIND11_TYPE_CASTER(type, _("datetime.timedelta"));

View File

@ -48,6 +48,11 @@ std::chrono::microseconds test_chrono7(std::chrono::microseconds t) {
return t;
}
// Float durations (issue #719)
std::chrono::duration<double> test_chrono_float_diff(std::chrono::duration<float> a, std::chrono::duration<float> b) {
return a - b;
}
test_initializer chrono([] (py::module &m) {
m.def("test_chrono1", &test_chrono1);
m.def("test_chrono2", &test_chrono2);
@ -56,4 +61,5 @@ test_initializer chrono([] (py::module &m) {
m.def("test_chrono5", &test_chrono5);
m.def("test_chrono6", &test_chrono6);
m.def("test_chrono7", &test_chrono7);
m.def("test_chrono_float_diff", &test_chrono_float_diff);
});

View File

@ -104,7 +104,7 @@ def test_chrono_steady_clock_roundtrip():
def test_floating_point_duration():
from pybind11_tests import test_chrono7
from pybind11_tests import test_chrono7, test_chrono_float_diff
import datetime
# Test using 35.525123 seconds as an example floating point number in seconds
@ -114,3 +114,7 @@ def test_floating_point_duration():
assert time.seconds == 35
assert 525122 <= time.microseconds <= 525123
diff = test_chrono_float_diff(43.789012, 1.123456)
assert diff.seconds == 42
assert 665556 <= diff.microseconds <= 665557