fix: allow assignment of time points of resolutions other than that of a system clock (#2481)
diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h
index 6127c65..ac3d34e 100644
--- a/include/pybind11/chrono.h
+++ b/include/pybind11/chrono.h
@@ -140,7 +140,7 @@
}
else return false;
- value = system_clock::from_time_t(std::mktime(&cal)) + msecs;
+ value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);
return true;
}
diff --git a/tests/test_chrono.cpp b/tests/test_chrono.cpp
index 1d79d4b..6537050 100644
--- a/tests/test_chrono.cpp
+++ b/tests/test_chrono.cpp
@@ -12,6 +12,24 @@
#include <pybind11/chrono.h>
#include <chrono>
+struct different_resolutions {
+ using time_point_h = std::chrono::time_point<
+ std::chrono::system_clock, std::chrono::hours>;
+ using time_point_m = std::chrono::time_point<
+ std::chrono::system_clock, std::chrono::minutes>;
+ using time_point_s = std::chrono::time_point<
+ std::chrono::system_clock, std::chrono::seconds>;
+ using time_point_ms = std::chrono::time_point<
+ std::chrono::system_clock, std::chrono::milliseconds>;
+ using time_point_us = std::chrono::time_point<
+ std::chrono::system_clock, std::chrono::microseconds>;
+ time_point_h timestamp_h;
+ time_point_m timestamp_m;
+ time_point_s timestamp_s;
+ time_point_ms timestamp_ms;
+ time_point_us timestamp_us;
+};
+
TEST_SUBMODULE(chrono, m) {
using system_time = std::chrono::system_clock::time_point;
using steady_time = std::chrono::steady_clock::time_point;
@@ -53,4 +71,14 @@
m.def("test_nano_timepoint", [](timestamp start, timespan delta) -> timestamp {
return start + delta;
});
+
+ // Test different resolutions
+ py::class_<different_resolutions>(m, "different_resolutions")
+ .def(py::init<>())
+ .def_readwrite("timestamp_h", &different_resolutions::timestamp_h)
+ .def_readwrite("timestamp_m", &different_resolutions::timestamp_m)
+ .def_readwrite("timestamp_s", &different_resolutions::timestamp_s)
+ .def_readwrite("timestamp_ms", &different_resolutions::timestamp_ms)
+ .def_readwrite("timestamp_us", &different_resolutions::timestamp_us)
+ ;
}
diff --git a/tests/test_chrono.py b/tests/test_chrono.py
index 7678390..ae24b7d 100644
--- a/tests/test_chrono.py
+++ b/tests/test_chrono.py
@@ -200,3 +200,13 @@
time = datetime.datetime.now()
time1 = m.test_nano_timepoint(time, datetime.timedelta(seconds=60))
assert(time1 == time + datetime.timedelta(seconds=60))
+
+
+def test_chrono_different_resolutions():
+ resolutions = m.different_resolutions()
+ time = datetime.datetime.now()
+ resolutions.timestamp_h = time
+ resolutions.timestamp_m = time
+ resolutions.timestamp_s = time
+ resolutions.timestamp_ms = time
+ resolutions.timestamp_us = time