[Python-Dev] PEP: New timestamp formats (original) (raw)
Victor Stinner victor.stinner at haypocalc.com
Thu Feb 2 13:16:33 CET 2012
- Previous message: [Python-Dev] PEP: New timestamp formats
- Next message: [Python-Dev] PEP: New timestamp formats
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I'd add datetime.timedelta to this list. It's exactly what timestamps are, after all - the difference between the current time and the relevant epoch value.
Ah yes, I forgot to mention it, whereas it is listed in the "final timestamp formats list" :-)
* a) (sec, nsec): C timespec structure, useful for os.futimens() for example * b) (sec, floatpart, exponent): value = sec + floatpart * 10**exponent * c) (sec, floatpart, divisor): value = sec + floatpart / divisor
The format (a) and (b) may loose precision if the clock divisor is not a power of 10. Format (b) only loses precision if the exponent chosen for a given value is too small relative to the precision of the underlying timer (it's the same as using decimal.Decimal in that respect).
Let's take an NTP timestamp in format (c): (sec=0, floatpart=100000000, divisor=2**32):
Decimal(100000000) * Decimal(10)**-10 Decimal('0.0100000000') Decimal(100000000) / Decimal(2)**32 Decimal('0.023283064365386962890625')
You have an error of 57%. Or do you mean that not only 232 should be modified, but also 100000000? How do you adapt 100000000 (floatpart) when changing the divisor (232 => 10**-10)? The format (c) avoids an operation (base^exponent) and avoids loosing precision.
There is the same issue with QueryPerformanceFrequency and QueryPerformanceCounter used by time.clock(), the frequency is not a power of any base.
I forgot to mention another advantage of (c), used by my patch for the Decimal format: you can get the exact resolution of the clock directly: 1/divisor. It works for any divisor (not only base^exponent).
By the way, the format (c) can be simplified as a fraction: (numerator, denominator) using (seconds * divisor + floatpart, divisor). But this format is less practical to implement a function creating a timestamp.
Callback and creating a new module to convert timestamps (...) Such an API could only become limiting if timestamps ever become something other than "the difference in time between right now and the relevant epoch value", and that's a sufficiently esoteric possibility that it really doesn't seem worthwhile to take it into account.
It may be interesting to support a different start date (other than 1970.1.1), if we choose to support broken-down timestamps (e.g. datetime.datetime).
The PEP should also mention PJE's suggestion of creating a new named protocol specifically for the purpose (with a signature based on one of the proposed tuple formats) (...)
Ok, I will add it.
Rather than being timestamp specific, such a protocol would be a general numeric protocol. If (integer, numerator, denominator) is used (i.e. a "mixed number" in mathematical terms), then "frommixed" would be an appropriate name. If (integer, fractional, exponent) is used (i.e. a fixed point notation), then "fromfixed" would work.
# Algorithm for a "from mixed numbers" protocol, assuming division doesn't lose precision... def frommixed(cls, integer, numerator, denominator): return cls(integer) + cls(numerator) / cls(denominator)
Even if I like the idea, I don't think that we need all this machinery to support nanosecond resolution. I should maybe forget my idea of using datetime.datetime or datetime.timedelta, or only only support int, float and decimal.Decimal.
datetime.datetime and datetime.timedelta are already compatible with Decimal (except that they may loose precision because of an internal conversion to float): datetime.datetime.fromtimestamp(t) and datetime.timedelta(seconds=t).
If we only support int, float and Decimal, we don't need to add a new protocol, hardcoded functions are enough :-)
os.stat: add new fields -----------------------
It was proposed to add 3 fields to os.stat() structure to get nanoseconds of timestamps. It's worth noting that the challenge with this is that it's potentially time consuming to populating the extra fields, and that this approach doesn't help with the time APIs that return timestamps directly.
New fields can be optional (add a flag to get them), but I don't like the idea of a structure with a variable number of fields, especially because os.stat() structure can be used as a tuple (get a field by its index).
Patching os.stat() doesn't solve the problem for the time module anyway.
Add an argument to change the result type ----------------------------------------- There should also be a description of the "set a boolean flag to request high precision output" approach.
You mean something like: time.time(hires=True)? Or time.time(decimal=True)?
Victor
- Previous message: [Python-Dev] PEP: New timestamp formats
- Next message: [Python-Dev] PEP: New timestamp formats
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]