[Python-Dev] datetime and timedelta enhancement

Victor Stinner victor.stinner at haypocalc.com
Fri Nov 14 23:59:03 CET 2008


Hi,

There are some interresting tickets about the datetime module:
#1673409: datetime module missing some important methods
#1083: Confusing error message when dividing timedelta using /
#2706: datetime: define division timedelta/timedelta
#4291: Allow Division of datetime.timedelta Objects

Wanted features:
1- convert a datetime object to an epoch value (numbers of seconds since 
   the 1st january 1970), eg. with a new totimestamp() method
2- convert a timedelta to a specific unit (eg. seconds, days, weeks, etc.)
3- compute the ratio of two timedelta, eg. for a progress bar

--

About (1), no patch is available yet. Some points are not fixed yet:
 a- use an integer to avoid floating point problems?
 b- use a float to keep the microseconds?
 c- limit the datetime to the time_t type (32 bits signed integer)?
    Which mean the following range:

>>> from datetime import datetime, timedelta
>>> t0 = datetime(1970, 1, 1, 0, 0, 0)
>>> print t0 + timedelta(seconds=-2**31), "-", t0 + timedelta(seconds=2**31-1)
1901-12-13 20:45:52 - 2038-01-19 03:14:07

The following point may answer to questions (a) and (b)...

--

For the points (2) and (3): webograph and belopolsky proposed to use the 
division of two timedelta objects. Examples (using the patch attached to 
#2706):

>>> from __future__ import division
>>> from datetime import datetime, timedelta
>>> one_second = timedelta(seconds=1)
>>> print timedelta(hours=1, minutes=1, microseconds=3) / one_second
3660.000003
>>> print timedelta(hours=1, minutes=1, microseconds=3) // one_second
3660
>>> print divmod(timedelta(hours=1, minutes=1, microseconds=3), one_second)
(3660L, datetime.timedelta(0, 0, 3))

We have the float representation, the integer part of the division, and the 
integer part + the remainder as a timedelta object. You have the choice to 
use the best format for your needs :)

Use another denominator to get other units, eg.
   weeks = dt / timedelta(days=7)

Then come the question of the accepted types:
   timedelta / float?
   divmod(timedelta, int)?
   etc.

--

About the conversion of a datetime object to time_t, the division can be 
reused like that:

>>> epoch = datetime.fromtimestamp(0)
>>> print epoch
1970-01-01 01:00:00
>>> d = datetime.fromtimestamp(34930.5)
>>> (d - epoch) / timedelta(seconds=1)   # integer
34930.5
>>> (d - epoch) // timedelta(seconds=1)  # float
34930L

datetime.totimestamp() can be implemented to produce a float in range [-2**31; 
2**31-1]. Why a float? To be symetric with fromtimestamp()! If you need 
older/newer timestamp or you want integers, use the examples with the 
divison.

-- 
Victor Stinner aka haypo
http://www.haypocalc.com/blog/


More information about the Python-Dev mailing list