-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
datetime: define division timedelta/timedelta #46958
Comments
i suggest that division be defined for timedelta1/timedelta2, in that use case aside from the obvious how-many-times-does-a-fit-into-b, this solves the from datetime import timedelta
duration = timedelta(hours=1.5, seconds=20)
print "Until the time is up, you can listen to 'We will rock you' %d
times."%(duration//timedelta(minutes=5, seconds=3))
import time
time.sleep(duration/timedelta(seconds=1)) history this issue follows a discussion on python-list, re-initiated by [1]. there have previously been similar feature requests on datetime, most of the only issue i've seen that can be relevant here is the patch i've written a patch against svn trunk revision 62520. it uses function pointers to reduce code duplication; in case this i familiar with c but not experienced, especially with the python ways i've also added test, but am not sure what has to be tested and what not. compatibility only cases in which division would fail without the patch are changed. [1] <mid:4813CD56.40800@eml.cc>, |
this is the mentioned patch without the function pointers, in case it |
I attaching webograph's patch updated to revision 67223 where I added a I am +1 on the floor divide changes (allowing timedelta // timedelta), >>> timedelta(1)/2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'datetime.timedelta' and
'int'
>>> timedelta(1)/timedelta(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'datetime.timedelta' and
'datetime.timedelta' With this patch, timedelta(1)/2 is still unsupported, but >>> timedelta(1)/timedelta(2)
0.5 Note that this is probably correct behavior because timedelta/int true Also, I've added a test that demonstrates the following behavior: >>> int(timedelta.min/(timedelta.min//3))
2 This is not a bug in webograph's patch, but rather a bug in long true |
Why not also implementing divmod()? It's useful to split a timedelta def formatTimedelta(delta):
"""
>>> formatTimedelta(timedelta(hours=1, minutes=24, seconds=19))
'1h 24min 19sec'
"""
hours, minutes = divmodTimedelta(delta, timedelta(hours=1))
minutes, seconds = divmodTimedelta(minutes, timedelta(minutes=1))
seconds, fraction = divmodTimedelta(seconds, timedelta(seconds=1))
return "{0}h {1}min {2}sec".format(hours, minutes, seconds) My implementation gives divmod(timedelta, timedelta) -> (long, def formatSeconds(seconds):
"""
>>> formatTimedelta(1*3600 + 24*60 + 19)
'1h 24min 19sec'
"""
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
return "{0}h {1}min {2}sec".format(hours, minutes, seconds)
About my new patch:
- based on datetime_datetime_division_dupcode.patch
- create divmod() operation on (timedelta, timedelta)
- add unit tests for the division (floor and true division) and
divmod
- update the documentation for the true division and divmod |
On Fri, Nov 14, 2008 at 12:51 PM, STINNER Victor <report@bugs.python.org> wrote:
I agree and in this case mod should probably be implemented too. With your patch: Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for %: 'datetime.timedelta' and
'datetime.timedelta' |
Also, why not >>> divmod(timedelta(3), 2)
(datetime.timedelta(1), datetime.timedelta(1)) ? And where do we stop? :-) On Fri, Nov 14, 2008 at 1:02 PM, Alexander Belopolsky
<belopolsky@users.sourceforge.net> wrote:
> On Fri, Nov 14, 2008 at 12:51 PM, STINNER Victor
<report@bugs.python.org> wrote:
>>
>> STINNER Victor <victor.stinner@haypocalc.com> added the comment:
>>
>> Why not also implementing divmod()? It's useful to split a timedelta
>> into, for example, (hours, minutes, seconds):
>
> I agree and in this case mod should probably be implemented too.
>
> With your patch:
>
>>>> timedelta(3)%timedelta(2)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for %: 'datetime.timedelta' and
> 'datetime.timedelta'
> |
Since timedelta(3) // 2 is already accepted, divmod should also accept With the last patch and "from __future__ import division", we support: What do you think about: |
While I agree that divmod may be useful, your particular use case is def formatTimedelta(delta):
return "{0}h {1}min {2}sec".format(*str(delta).split(':')) or you can convert delta to time using an arbitrary anchor date and (1, 24, 19) (depending on your needs you may want to add delta.days*24 to the hours) On Fri, Nov 14, 2008 at 12:51 PM, STINNER Victor <report@bugs.python.org> wrote:
>
> STINNER Victor <victor.stinner@haypocalc.com> added the comment:
>
> Why not also implementing divmod()? It's useful to split a timedelta
> into, for example, (hours, minutes, seconds):
>
> def formatTimedelta(delta):
> """
> >>> formatTimedelta(timedelta(hours=1, minutes=24, seconds=19))
> '1h 24min 19sec'
> """
> hours, minutes = divmodTimedelta(delta, timedelta(hours=1))
> minutes, seconds = divmodTimedelta(minutes, timedelta(minutes=1))
> seconds, fraction = divmodTimedelta(seconds, timedelta(seconds=1))
> return "{0}h {1}min {2}sec".format(hours, minutes, seconds)
> |
On Fri, Nov 14, 2008 at 1:28 PM, STINNER Victor <report@bugs.python.org> wrote:
+1 +1 +1 timedelta % float -> timedelta (because int % float -> int works) ? +1 +1 divmod(timedelta, float) -> (timedelta, timedelta) ? -1 Only timedelta / timedelta should produce dimensionless numbers. |
Oops, the tracker ate some lines from e-mail. Reposting through the On Fri, Nov 14, 2008 at 1:28 PM, STINNER Victor <report@bugs.python.org>
timedelta % float -> timedelta (because int % float -> int works) ?
divmod(timedelta, float) -> (timedelta, timedelta) ?
Only timedelta / timedelta should produce dimensionless numbers. Forward |
OMG, this is ugly! Conversion to string and reparse the formatted text :-/ ['4 days, 1', '32', '01']
>>> str(timedelta(hours=1, minutes=32, seconds=1, microseconds=2)).split(":")
['1', '32', '01.000002']
How? I don't understand your suggestion.
The goal of the new operators (timedelta / timedelta, divmod(timedelta, |
haypo> How? I don't understand your suggestion. Sorry, another case of mail to tracker bug. Here is what I wrote: """ >>> x = datetime(1,1,1) + timedelta(hours=1, minutes=24, seconds=19)
>>> x.hour,x.minute,x.second
(1, 24, 19) (depending on your needs you may want to add delta.days*24 to the hours) but tracker ate the '>>>' lines :-( |
@WeboGraph: time_gmtime() and time_localtime() already use function |
I don't understand this; why should the division mode affect I vote +1 for timedelta/timedelta and timedelta/float (regardless |
By the way, I assume that any plan to add this division would also include timedelta * float -> timedelta. It wouldn't make a whole lot of sense to have one without the other. |
Some examples to help the choice (using the last patch). int 2L
>>> print dt2 * 2
3:08:38
>>> print dt1 - dt2 * 2
0:51:22
>>> divmod(dt1, dt2)
(2L, datetime.timedelta(0, 3082))
>>> print timedelta(0, 3082)
0:51:22 In 4 hours, you can watch the movie twice, and then your have 51 minutes left. Operations used:
float 0.21258172822053367
>>> "Progress: %.1f%%" % ((dt1 / dt2) * 100.0)
'Progress: 21.3%'
>>> dt2 * 0.75
...
TypeError: unsupported operand type(s) for *: 'datetime.timedelta' and 'float'
>>> print (dt2 * 3) // 4
1:10:44.250000 If you are seen this movie since 20 minutes, you're at 21% of the total. If Note: timedelta * float is not implemented yet. Operations used:
|
On Sat, Nov 15, 2008 at 5:08 AM, Mark Dickinson <report@bugs.python.org> wrote:
Here is how I think about this: timedeltas are integers in units of
Because they are integers. If we had a floattimedelta type that would
What do you vote timedelta/timedelta should produce in floor division |
I'm finally opposed to datetime.totimedelta() => float, I |
I think datetime division would be a fine application for Fractions. |
Hi all, I'm trying to help out by reviewing issues in the tracker... so this is
Evaluation: Since both time deltas are quantitative values of the same Recommendation: That this functionality be recommended for development
Evaluation: This makes total sense.
The alternative is an integer, but due to a lack of immediate clarity
A patch has been attached which implements some of this behaviour. I -T |
On Tue, Mar 10, 2009 at 5:15 PM, Tennessee Leeuwenburg
I don't think this alternative was ever seriously considered and no |
i don't think this can be solved in a way that is independent of the ( |
A comment on the two most recent patches... For both of these, we can >>> from datetime import timedelta
>>> td = timedelta(12)
>>> td
datetime.timedelta(12)
>>> td //= 3
>>> td
datetime.timedelta(4)
>>> td //= timedelta(2)
>>> td
2 # CHANGED VARIABLE TYPE! I think the last operation will trap unsuspecting programmers, and |
Well, this already happen with other types: >>> a = 100
>>> a //= 2.0
>>> a
50.0
>>> d = datetime.datetime.now()
>>> d -= datetime.datetime.now()
>>> d
datetime.timedelta(-1, 86391, 609000) See http://docs.python.org/reference/datamodel.html#object.\_\_iadd__ |
Is there a good reason why this issue is languishing? The requested functionality seems to be well motivated, simple to implement with few objections resolved in the discussion. I wonder if it would be helpful to limit this patch to 3.x series. That way some of the controversies about true vs. floor division would disappear and it will be easier to accept new features. |
It's too late for 2.7 anyway. |
I am attaching a forward port of Victor's timedelta_true_divide_divmod.patch to py3k. |
Why is divmod(timedelta, timedelta) supported but not timedelta % timedelta? I think if one is implemented, the other should be too. |
On Mon, Apr 19, 2010 at 4:09 PM, Mark Dickinson <report@bugs.python.org>wrote: I noticed that as I was porting Victor's patch. I did not add timedelta % I was contemplating opening a separate RFE for divmod(timedelta, int) |
By the way, the patch looks good to me, as far as it goes, and I'm +1 on adding all this. I only have the tiniest of nits:
One other thought: with this division operation added, it might be nice to add constants like td_hour, td_minute, etc. to the module. Then the perennial 'how can I convert my timedelta x to minutes' questions could be answered with 'just do x/td_minute'. I would personally find x/td_second to be a more obvious and natural way to find the total number of seconds in a timedelta than x.total_seconds. I also quite like the idea of being able to create a 2.5-hour timedelta with something like 2*td_hour + 30*td_minute On the other hand, maybe such constants would just be added clutter, since it's easy to create them when needed. |
Tennessee, are you still tracking this issue? If not, can I steal it from you. :)
Mmm. Interesting. :) I think it would be fine to add timedelta % timedelta in this patch, and then open another feature request for timedelta % int and friends as you suggest. I don't think divmod(timedelta, timedelta) should go in if timedelta % timedelta doesn't also go in.
Perhaps; I haven't seen much opposition to these ideas anyway---I think the only reason they haven't been implemented yet is lack of round-tuits. I'd be +1 on accepting the current patch if timedelta % timedelta were added to it. |
Hmm. Having timedelta // int work is *really* peculiar, since it can only be made sense of with reference to some implicit particular chosen unit of time; in this case, that unit of time is apparently microseconds, as far as I can tell. Surely there aren't any applications for timedelta // int?! The operation just doesn't make dimensional sense, since it involves taking floor of a timedelta. I vote -3.2 minutes on extending this craziness by adding timedelta % int or divmod(timedelta, int). |
I should be able to add timedelta % timedelta and fix the nits that Mark mentioned tonight. |
On Tue, Apr 20, 2010 at 6:46 AM, Mark Dickinson <report@bugs.python.org>wrote:
Hi Mark, Please feel free to steal it from me! Wonderful to see some movement on this
I'm an incrementalist -- I'm happy with one step at a time, so for what it's Regards, |
New patch, issue2706a.diff, implements timedelta % timedelta and addresses Mark's code review comments. With respect to Mark's 2*td_hour + 30*td_minute On the other hand, maybe such constants would just be added clutter, since it's easy to create them when needed. I dislike this proposal for the same reason as Mark likes it: 2*td_hour + 30*td_minute == timedelta(hours=2, minutes=30) is a violation of TOOWTDI. |
Stealing from Tennessee... Patch committed to py3k in r80290, r80291, with some minor tweaks and fixes:
Thanks, Alexander! |
Grr. s/whatsnew/versionadded/ |
Can someone (Mark?) add an acknowledgment for Victor Stinner to the NEWS file? My py3k patch was 90% code from Victor's trunk patch. |
Ah, yes. Sorry, Victor! There's actually no acknowledgement in Misc/NEWS: it's not *that* common to put acknowledgements there, and I'm not sure it's necessary here, but I've fixed the commit message. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: