Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1)

Unified Diff: Modules/_datetimemodule.c

Issue 23517: datetime.utcfromtimestamp rounds results incorrectly
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« Lib/test/datetimetester.py ('K') | « Lib/test/datetimetester.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Modules/_datetimemodule.c Tue Sep 08 09:59:02 2015 +0300
+++ b/Modules/_datetimemodule.c Wed Sep 09 01:59:39 2015 +0200
@@ -4113,6 +4113,17 @@ datetime_from_timet_and_us(PyObject *cls
tzinfo);
}
+/* Round to nearest with ties going to nearest even integer. */
+static double
+round_half_even(double x)
storchaka 2015/09/10 22:27:10 May be use lrint() if available?
+{
+ double rounded = round(x);
+ if (fabs(x-rounded) == 0.5)
+ /* halfway case: round to even */
+ rounded = 2.0*round(x/2.0);
+ return rounded;
+}
+
/* Internal helper.
* Build datetime from a Python timestamp. Pass localtime or gmtime for f,
* to control the interpretation of the timestamp. Since a double doesn't
@@ -4124,12 +4135,29 @@ static PyObject *
datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
PyObject *tzinfo)
{
+ double dtime;
time_t timet;
- long us;
-
- if (_PyTime_ObjectToTimeval(timestamp, &timet, &us, _PyTime_ROUND_DOWN) == -1)
+ double fraction;
+ int us;
+
+ dtime = PyFloat_AsDouble(timestamp);
+ if (dtime == -1.0 && PyErr_Occurred())
return NULL;
- return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
+
+ if (_PyTime_ObjectToTime_t(timestamp, &timet, _PyTime_ROUND_DOWN) < 0)
+ return NULL;
+
+ fraction = dtime - (double)timet;
+ us = (int)round_half_even(fraction * 1e6);
+ if (us < 0) {
+ us += 1000000;
+ timet -= 1;
+ }
+ else if (us >= 1000000) {
+ us -= 1000000;
+ timet += 1;
+ }
+ return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
}
/* Internal helper.
« Lib/test/datetimetester.py ('K') | « Lib/test/datetimetester.py ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+