Skip to content

Commit ed876f2

Browse files
committed
update delta_new
1 parent f8d3402 commit ed876f2

File tree

2 files changed

+23
-38
lines changed

2 files changed

+23
-38
lines changed

Lib/test/datetimetester.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,6 @@ def test_basic_attributes(self):
669669
self.assertEqual(td.microseconds, us)
670670

671671
def test_total_seconds(self):
672-
if 'Pure' not in self.__class__.__name__: return # BUG
673672
td = timedelta(days=365)
674673
self.assertEqual(td.total_seconds(), 31536000.0)
675674
for total_seconds in [123456.789012, -123456.789012, 0.123456, 1e-9, -1e-9, 0, 1e6]:
@@ -1694,13 +1693,20 @@ def test_resolution_info(self):
16941693
self.assertIsInstance(self.theclass.resolution, timedelta)
16951694
self.assertTrue(self.theclass.max > self.theclass.min)
16961695

1696+
def is_pure_test(self):
1697+
return 'Pure' in self.__class__.__name__
1698+
16971699
def test_extreme_timedelta(self):
1698-
if 'Pure' not in self.__class__.__name__: return # BUG
16991700
big = self.theclass.max - self.theclass.min
17001701
# 3652058 days, 86399 seconds, 999999 microseconds, 999 nanoseconds
1701-
n = ((big.days*24*3600 + big.seconds)*1000000 + big.microseconds) * 1000 + big.nanoseconds
1702-
# n == 315537897599999999999 ~= 2**68.1
1703-
justasbig = timedelta(0, 0, 0, n)
1702+
if self.is_pure_test():
1703+
n = ((big.days*24*3600 + big.seconds)*1000000 + big.microseconds) * 1000 + big.nanoseconds
1704+
# n == 315537897599999999999 ~= 2**68.1 ;
1705+
justasbig = timedelta(0, 0, 0, n)
1706+
else:
1707+
n = ((big.days*24*3600 + big.seconds)*1000000 + big.microseconds)
1708+
# n == 315537897599999999 ~= 2**58.13
1709+
justasbig = timedelta(0, 0, n, big.nanoseconds)
17041710
self.assertEqual(big, justasbig)
17051711
self.assertEqual(self.theclass.min + big, self.theclass.max)
17061712
self.assertEqual(self.theclass.max - big, self.theclass.min)

Modules/_datetimemodule.c

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,10 +2930,6 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
29302930
y = accum("microseconds", x, us, _PyLong_GetOne(), &leftover_us);
29312931
CLEANUP;
29322932
}
2933-
// if (ns) {
2934-
// y = accum("nanoseconds", x, ns, CONST_US_PER_NANOSECOND(st), &leftover_us);
2935-
// CLEANUP;
2936-
// }
29372933
if (ms) {
29382934
y = accum("milliseconds", x, ms, CONST_US_PER_MS(st), &leftover_us);
29392935
CLEANUP;
@@ -2958,34 +2954,19 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
29582954
y = accum("weeks", x, week, CONST_US_PER_WEEK(st), &leftover_us);
29592955
CLEANUP;
29602956
}
2957+
long leftover_ns = 0;
2958+
if (ns) {
2959+
leftover_ns += PyLong_AsLong(ns);
2960+
}
29612961
if (leftover_us) {
2962-
/* Round to nearest whole # of us, and add into x. */
2963-
double whole_us = round(leftover_us);
2964-
int x_is_odd;
2965-
PyObject *temp;
2966-
2967-
if (fabs(whole_us - leftover_us) == 0.5) {
2968-
/* We're exactly halfway between two integers. In order
2969-
* to do round-half-to-even, we must determine whether x
2970-
* is odd. Note that x is odd when it's last bit is 1. The
2971-
* code below uses bitwise and operation to check the last
2972-
* bit. */
2973-
temp = PyNumber_And(x, _PyLong_GetOne()); /* temp <- x & 1 */
2974-
if (temp == NULL) {
2975-
Py_DECREF(x);
2976-
goto Done;
2977-
}
2978-
x_is_odd = PyObject_IsTrue(temp);
2979-
Py_DECREF(temp);
2980-
if (x_is_odd == -1) {
2981-
Py_DECREF(x);
2982-
goto Done;
2983-
}
2984-
whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2962+
long integral_us = (long)leftover_us;
2963+
// TODO: should use py_round; previous rounding was also wrong as it checks for x_is_odd instead of x + whole_us
2964+
leftover_ns = round((leftover_us - integral_us) * 1000);
2965+
if (leftover_ns > 999) {
2966+
integral_us++;
2967+
leftover_ns -= 1000;
29852968
}
2986-
2987-
temp = PyLong_FromLong((long)whole_us);
2988-
2969+
PyObject *temp = PyLong_FromLong(integral_us);
29892970
if (temp == NULL) {
29902971
Py_DECREF(x);
29912972
goto Done;
@@ -2996,9 +2977,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
29962977
}
29972978

29982979
self = microseconds_to_delta_ex(x, type);
2999-
if (ns) {
3000-
SET_TD_NANOSECONDS((PyDateTime_Delta *)self, PyLong_AsLong(ns));
3001-
}
2980+
SET_TD_NANOSECONDS((PyDateTime_Delta *)self, leftover_ns);
30022981
Py_DECREF(x);
30032982

30042983
Done:

0 commit comments

Comments
 (0)