msg155449 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-03-12 13:13 |
Please allow using decimals as arguments to `timedelta`, so the following code won't raise an exception:
Python 3.3.0a1 (default, Mar 4 2012, 17:27:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import decimal
>>> datetime.timedelta(hours=decimal.Decimal(7))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported type for timedelta hours component: Decimal
It's really annoying to have to convert all the arguments to `float` every time I instantiate a `timedelta`.
|
msg155583 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2012-03-13 09:11 |
The PEP 410 was rejected. See also the issue #13882.
|
msg155587 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-03-13 10:16 |
I'm not proposing that `timedelta` will use `Decimal` internally, but that it would handle the conversion to `float` itself, instead of the user having to do it.
|
msg155602 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2012-03-13 12:51 |
Attached patch changes timedelta constructor to accept decimal.Decimal.
See also the issue #14180.
|
msg155609 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-03-13 13:37 |
Thanks for the patch!
|
msg155627 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2012-03-13 16:11 |
I am -0 on the feature and -1 on the implementation. Conversion from Decimal to float is explicit by design. Decimal gives the user fine control over rounding issues allowing for either exact arithmetics (trapping inexact operation) or one of several rounding modes.
This said, timedelta(<decimal>) is not much worse than float(<decimal>), so I will be only -0 if the implementation is such that (1) timedelta(<decimal>) does no loose precision over the entire range of timedelta and rounding is documented; and (2) implementaton does not require an explicit import decimal inside the datetime module.
|
msg156371 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2012-03-20 00:14 |
My patch looses precision for big numbers. It's better to convert Decimal to a number of microseconds.
Wrong:
>>> value=86400*365.25*999999+1e-6; print(datetime.timedelta(seconds=value))
365249634 days, 18:00:00
>>> value=decimal.Decimal(86400*365.25*999999)+decimal.Decimal('1e-6'); print(datetime.timedelta(seconds=float(value)))
365249634 days, 18:00:00
Correct:
>>> value=decimal.Decimal(86400*365.25*999999)+decimal.Decimal('1e-6'); print(datetime.timedelta(microseconds=int(value*decimal.Decimal(10**6))))
365249634 days, 18:00:00.000001
I'm not completly conviced by the need of supporting Decimal in timedelta constructor. Why do you use Decimal if the result should be a timedelta? Why not using timedelta directly?
|
msg156393 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-03-20 10:18 |
"I'm not completly conviced by the need of supporting Decimal in timedelta constructor. Why do you use Decimal if the result should be a timedelta? Why not using timedelta directly?"
What do you mean, "Why not using timedelta directly?" How could I use timedelta directly in the timedelta constructor? I'm creating a timedelta, I don't have one ready.
I'm getting an `n_hours` variable for some component of my system. And this value happens to come as a `Decimal`. I want to create a `timedelta` out of it. So I'd want to be able to do `timedelta(hours=n_hours)` rather than `timedelta(hours=float(n_hours))`.
|
msg156396 - (view) |
Author: STINNER Victor (vstinner) * |
Date: 2012-03-20 11:35 |
"I'm getting an `n_hours` variable for some component of my system.
And this value happens to come as a `Decimal`."
Can't you modify your program to use timedelta instead of Decimal for n_hours?
|
msg156398 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-03-20 11:39 |
In some cases we indeed use a timedelta directly, but sometimes we get a "number of hours", and in those cases it's more convenient for us to work with "number of hours" directly.
|
msg170746 - (view) |
Author: Mark Dickinson (mark.dickinson) * |
Date: 2012-09-19 18:56 |
> (1) timedelta(<decimal>) does no loose precision over the entire range
> of timedelta and rounding is documented;
Agreed that this should be a requirement.
|
msg170748 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2012-09-19 19:04 |
Mark wrote in his comment on issue 15975:
> we're looking at significant extra code to implement
> Decimal * timedelta
Not necessarily. I will only support adding this feature if it can be done without making datetime know about Decimal. If we can agree on a lossless protocol to communicate floating pointing numbers of different base (or even more generally rational numbers), datetime module can support this protocol and allow all kinds of numbers in its constructors without much extra code.
|
msg170749 - (view) |
Author: Mark Dickinson (mark.dickinson) * |
Date: 2012-09-19 19:05 |
@Ram Rachum: out of curiosity, where are your Decimal objects coming from in the first place?
|
msg170750 - (view) |
Author: Mark Dickinson (mark.dickinson) * |
Date: 2012-09-19 19:07 |
> If we can agree on a lossless protocol to communicate floating pointing
> numbers of different base
What sort of thing did you have in mind? This is sounding like a PEP-level proposal.
|
msg170751 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-09-19 19:09 |
@mark.dickinson: Many different sources. One example is decimal fields on Django, used for dollar amounts.
|
msg170753 - (view) |
Author: Alexander Belopolsky (Alexander.Belopolsky) |
Date: 2012-09-19 19:20 |
On Wed, Sep 19, 2012 at 3:09 PM, Ram Rachum <report@bugs.python.org> wrote:
> One example is decimal fields on Django, used for dollar amounts.
.. and since time is money and money is time we should support easy
conversion between the two. :-)
|
msg170754 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-09-19 19:24 |
I hope this was intended as a joke. If this was an actual criticism, let me know so I could explain why it makes sense.
|
msg170758 - (view) |
Author: Alexander Belopolsky (Alexander.Belopolsky) |
Date: 2012-09-19 19:34 |
On Wed, Sep 19, 2012 at 3:24 PM, Ram Rachum <report@bugs.python.org> wrote:
> I hope this was intended as a joke. If this was an actual criticism, let me know so
> I could explain why it makes sense.
It was both. Yes, any use cases will be helpful. Timedelta is
already a decimal with six fractional digits, so it is natural to
desire having direct Decimal to timedelta conversion, but without
important use-case this feature will be hard to sell.
|
msg170769 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-09-19 20:32 |
I can think of millions of use cases. Here's a random one out of those millions: A client is entitled to X hours of service a month. We grant him a promotion where he is allowed 15% more than x, i.e. 1.15*x. But that number, 1.15, is stored in a Django decimal field. We try to multiply 1.15 by the timedelta X and it fails.
|
msg170771 - (view) |
Author: Alexander Belopolsky (Alexander.Belopolsky) |
Date: 2012-09-19 20:57 |
On Wed, Sep 19, 2012 at 4:32 PM, Ram Rachum <report@bugs.python.org> wrote:
> But that number, 1.15, is stored in a Django decimal field.
My criticism was towards the idea that one may need to multiply
timedelta by a dollar amount or convert a dollar amount to a
timedelta. Storing dollar amounts is an important use case for
Decimal and there are several reasons why Decimal is a better choice
than float for this. On the other hand, I don't see why use of
Decimal would be required in your example.
Do you have any real world use cases where Decimal is clearly
preferred over float and there is a need to multiply Decimals by time
deltas?
|
msg170773 - (view) |
Author: Ram Rachum (cool-RR) * |
Date: 2012-09-19 21:36 |
In the example I gave, Decimal is clearly preferred over float. Why would we use float to represent the ratio of the bonus to the client? Why would we risk imprecision there when Decimal provides us with perfect precision?
|
msg170776 - (view) |
Author: Alexander Belopolsky (Alexander.Belopolsky) |
Date: 2012-09-19 22:38 |
On Sep 19, 2012, at 5:36 PM, Ram Rachum <report@bugs.python.org> wrote:
> Why would we use float to represent the ratio of the bonus to the client?
Because float is the builtin type that Python provides to represent such quantities.
> Why would we risk imprecision there when Decimal provides us with perfect precision?
Python float is a much simpler and more efficient type than Decimal. One should have a really good reason to introduce Decimal in the program. In case of money, Decimal provides a *lower* precision alternative to float together with the control over rounding direction. This is important in applications where fractions of a penny have to be dealt with in very precise manner.
In your application, float is a perfectly good type to represent 15% bonus. Even if your customers insist on microsecond precision, float is good enough and timedelta resolution will prevent you from supporting higher precision anyways.
As I mentioned before, I would be happy to see greater interoperability between numerical types in Python and interoperability between timedelta and Decimal may come as a side benefit of that effort. However, I don't find your use case to be compelling enough to either justify special case code or to motivate a more general effort.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:57:27 | admin | set | github: 58470 |
2014-10-14 15:00:08 | skrah | set | nosy:
- skrah
|
2012-09-19 22:38:02 | Alexander.Belopolsky | set | messages:
+ msg170776 |
2012-09-19 21:36:56 | cool-RR | set | messages:
+ msg170773 |
2012-09-19 20:57:20 | Alexander.Belopolsky | set | messages:
+ msg170771 |
2012-09-19 20:32:06 | cool-RR | set | messages:
+ msg170769 |
2012-09-19 19:34:10 | Alexander.Belopolsky | set | messages:
+ msg170758 |
2012-09-19 19:24:43 | cool-RR | set | messages:
+ msg170754 |
2012-09-19 19:20:18 | Alexander.Belopolsky | set | nosy:
+ Alexander.Belopolsky messages:
+ msg170753
|
2012-09-19 19:09:43 | cool-RR | set | messages:
+ msg170751 |
2012-09-19 19:07:38 | mark.dickinson | set | messages:
+ msg170750 |
2012-09-19 19:05:21 | mark.dickinson | set | messages:
+ msg170749 |
2012-09-19 19:04:36 | belopolsky | set | messages:
+ msg170748 |
2012-09-19 18:58:00 | mark.dickinson | link | issue15975 superseder |
2012-09-19 18:56:53 | mark.dickinson | set | messages:
+ msg170746 |
2012-09-19 18:55:28 | mark.dickinson | set | versions:
+ Python 3.4, - Python 3.3 |
2012-03-20 11:39:58 | cool-RR | set | messages:
+ msg156398 |
2012-03-20 11:35:48 | vstinner | set | messages:
+ msg156396 |
2012-03-20 10:18:02 | cool-RR | set | messages:
+ msg156393 |
2012-03-20 00:14:54 | vstinner | set | messages:
+ msg156371 |
2012-03-20 00:03:09 | vstinner | set | nosy:
+ skrah
|
2012-03-13 16:11:30 | belopolsky | set | type: enhancement messages:
+ msg155627 |
2012-03-13 13:37:25 | cool-RR | set | messages:
+ msg155609 |
2012-03-13 12:51:48 | vstinner | set | files:
+ timedelta_decimal.patch keywords:
+ patch messages:
+ msg155602
|
2012-03-13 10:16:01 | cool-RR | set | messages:
+ msg155587 |
2012-03-13 09:11:04 | vstinner | set | messages:
+ msg155583 |
2012-03-13 02:32:01 | eric.araujo | set | nosy:
+ rhettinger, facundobatista, mark.dickinson, belopolsky, vstinner
|
2012-03-12 13:13:07 | cool-RR | create | |