[Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review

Victor Stinner victor.stinner at gmail.com
Tue Feb 14 13:55:23 CET 2012


> A datetime module based approach would need to either use a mix of
> datetime.datetime() (when returning an absolute time) and
> datetime.timedelta() (when returning a time relative to an unknown
> starting point),

Returning a different type depending on the function would be
surprising and confusing.

time.clock_gettime(CLOCK_REALTIME) would return datetime.datetime,
whereas time.clock_gettime(CLOCK_MONOTONIC) would return
datetime.timedelta?

Or time.clock_gettime(CLOCK_REALTIME) would return datetime.timedelta
whereas time.time() would return datetime.datetime? What would be the
logic?

> or else just always return datetime.timedelta (even
> when we know the epoch and could theoretically make the time
> absolute).

datetime.timedelta is similar to decimal.Decimal, but I don't want to
support both, one is enough. I prefer Decimal because it is simpler
and "compatible" with float.

> In the former case, it may be appropriate to adopt a boolean flag API
> design and the "I want high precision time" request marker would just
> be "datetime=True". You'd then get back either datetime.datetime() or
> datetime.timedelta() as appropriate for the specific API.

A boolean flag has a problem with the import of the decimal module:
time.time(decimal=True) would need an implicit ("hidden") import of
the decimal module.

Another argument present in the PEP:
"The boolean argument API was rejected because it is not "pythonic".
Changing the return type with a parameter value is preferred over a
boolean parameter (a flag)."
http://www.python.org/dev/peps/pep-0410/#add-a-boolean-argument

> If handed a datetime value, you need to know the correct epoch value,
> do the subtraction, then extract the full precision timestamp from the
> resulting timedelta object.

datetime.datetime don't have a .totimestamp() method.

If I remember correctly, time.mktime(datetime.datetime.timetuple())
has issues with timezone and the DST.

> - implement __int__ and __float__ on timedelta (where the latter is
> just "self.total_seconds()" and the former
> "int(self.total_seconds())")

It looks like an hack. Why would float(timedelta) return seconds? Why
not minutes or nanoseconds? I prefer an unambiguously and explicit
.toseconds() method.

> The big problem is that datetime and
> timedelta pose a huge problem for compatibility with existing third
> party APIs that accept timestamp values.

I just think that datetime and timedelta are overkill and have more
drawbacks than advantages. FYI when I implemented datetime, it just
just implemented by calling datetime.datetime.fromtimestamp(). The
user can do an explicit call to this function, and
datetime.timedelta(seconds=ts) for timedelta.

> This is in stark contrast to what happens with decimal.Decimal:
> coercion to float() or int() will potentially lose precision, but
> still basically works. While addition and subtraction of floats will
> fail, addition and subtraction of integers works fine. To avoid losing
> precision, it's sufficient to just avoid the coercion.

Why would you like to mix Decimal and float? If you ask explicitly to
get Decimal timestamps, you should use Decimal everywhere or you lose
advantages of this type (and may get TypeError).

> I think the outline above really illustrates why the *raw* data type
> for timestamps should just be a number, not a higher level semantic
> type like timedelta or datetime. Eventually, you want to be able to
> express a timestamp as a number of seconds relative to a particular
> epoch. To do that, you want a number. Originally, we used ints, then,
> to support microsecond resolution, we used floats. The natural
> progression to support arbitrary resolutions is to decimal.Decimal.

Yep.

> Then, the higher level APIs can be defined in *terms* of that high
> precision number. Would it be nice if there was a PyPI module that
> provided APIs that converted the raw timestamps in stat objects and
> other OS level APIs into datetime() and timedelta() objects as
> appropriate?

Do you really need a module to call
datetime.datetime.fromtimestamp(ts) and
datetime.timedelta(seconds=ts)?

> timedelta.total_seconds() can be updated to accept a "timestamp" argument

Yes, it would be consistent with the other changes introduced by the PEP.

> Also, by using decimal.Decimal, we open up the possibility of, at some
> point in the future, switching to returning high precision values by
> default

I don't think that it is necessary. Few people need this precision and
float will always be faster than Decimal because float is implemented
in *hardware* (FPU).

I read somewhere that IBM plans to implement decimal float in their
CPU, but I suppose than it will also have a "small" size like 64 bits,
whereas 64 bits is not enough for a nanosecond resolution (same issue
than binary float).

> implicit promotion of floats to decimal values in binary
> operations without losing data

I don't think that such change would be accepted. You should ask
Stephan Krah or Mark Dickson :-)

--

I completed datetime, timedelta and boolean flag sections of the PEP 410.

Victor


More information about the Python-Dev mailing list