You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
datetime module missing some important methods #44656
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:
assignee=Noneclosed_at=<Date2010-04-21.18:03:30.573>created_at=<Date2007-03-04.11:59:05.000>labels= ['type-feature', 'library']
title='datetime module missing some important methods'updated_at=<Date2010-04-21.18:52:38.900>user='https://github.com/jribbens'
There is no datetime.totimestamp because the range
of time represented by a datetime object far
exceeds the range of a normal int-based Unix
timestamp (roughly 1970-2038). Datetime objects
before the start of the Unix epoch would be
represented by negative numbers. As far as I
know, the common Unix library functions which
accept epoch times wouldn't know what to do
with a negative number.
That said, you stated these missing methods
were important. Can you offer some use
cases which would support that contention?
I personally don't think a argument for
symmetry would be a convincing use case and
that's the only one I can think of.
jribbens commented on Sep 2, 2007
jribbensmannequin
MannequinAuthor
More actions
Almost everything you just said about time_t is wrong. time_t is signed,
and always has been (otherwise the 'end of time' for 32-bit time_t would
be 2106, not 2038). Also, time_t does not end at 2038 because nothing
says it must be 32 bits. Also, Python has 'long integers' which do not
overflow.
Also, I don't understand what you mean about use cases. The "use case"
is "dealing with anything which expects standard Unix time_t, for
example the Python standard library". The use case I have personally is
the program I was working on when I encountered the problem described in
this bug report. Also I think symmetry is a darn good argument. Why does
fromtimestamp exist if, as you claim, nobody uses time_t?
Jon> Almost everything you just said about time_t is wrong. time_t is
Jon> signed, and always has been (otherwise the 'end of time' for 32-bit
Jon> time_t would be 2106, not 2038). Also, time_t does not end at 2038
Jon> because nothing says it must be 32 bits. Also, Python has 'long
Jon> integers' which do not overflow.
My apologies about goofing up on the signedness of time_t. What are you
going to do with a long integer that you can't do with a datetime object?
You clearly can't pass it directly to any Unix library functions which
expect time_t. Converting it can overflow.
Jon> Also, I don't understand what you mean about use cases. The "use
Jon> case" is "dealing with anything which expects standard Unix time_t,
Jon> for example the Python standard library". The use case I have
Jon> personally is the program I was working on when I encountered the
Jon> problem described in this bug report. Also I think symmetry is a
Jon> darn good argument. Why does fromtimestamp exist if, as you claim,
Jon> nobody uses time_t?
What should datetime.datetime(9999, 1, 1).totimestamp() return? How would
you pass it to something which accepts a time_t? The fromtimestamp
functions work simply because the range of time_t is a proper subset of the
range of Python's datetime objects. Symmetry gets you little. In
situations where you need Unix timestamps and you know your datetime objects
are within the bounds representable by time_t, you can define a convenience
function:
This will, of course, fail if the year is too big or too small (and will
fail in platform-dependent ways if the underlying platform's range of
representable dates has different bounds than Unix does). Doing it without
resorting to calling time.mktime is also nontrivial. Under the covers the
datetime module currently uses platform functions to get time information
anyway. It doesn't do a lot of low-level time arithmethic itself.
Implementing fromtimestamp would require a fair amount of effort unless you
were willing to punt and just raise OverflowError for dates outside the
system's range.
Skip
tomster commented on Nov 2, 2007
tomstermannequin
Mannequin
More actions
unless I'm missing something important this will do the trick quite
nicely:
Jon> If we're expecting floating-point, then everything you said earlier
Jon> about the limitations of ints was a bit redundant ;-)
Yes, sorry. I responded to the mail without going back and reviewing the
entire thread. (It's been a couple months.) Note however that my example
to_timestamp() function converts the microseconds field to seconds and
include them in the result.
So, are we concluding that nothing needs to be added to the datetime module?
Skip
20 remaining items
srittau commented on Dec 15, 2008
srittaumannequin
Mannequin
More actions
A timedelta.toseconds method (or equivalent) makes no sense. The number
of seconds in a day is not fixed (due to leap seconds) and relying on
such a method would introduce subtle bugs. The only way to find out the
number of seconds in a range of dates is if you have a concrete date range.
About my method: I finally prefer datetime/datetime or
datetime//datetime instead of a toseconds() method. And to convert a
timestamp to a timestamp: see my patch attached to issue bpo-2736.
I also think totimestamp() on datetime objects would be useful, I've
missed it myself a couple of times. The return value should be similar
to that of time.time(), i.e. a float.
srittau commented on Dec 15, 2008
srittaumannequin
Mannequin
More actions
Leap second handling is usually configurable. Default on Debian Linux
(but similar on RHEL and SuSE):
(...) totimestamp() (...) return value should be similar
to that of time.time(), i.e. a float
float is a source of many problems (rounding problems), especially for
huge values: float is unable to store correctly microseconds for big
values: see msg75426. A simple tuple (int, int) is simple and there is
no rounding/float limit.
What you say is "with 99500 days or more, the microsecond error is
bigger than 90%". It means that with epoch starting at 1970, you can
still return timestamps with a 1-2 microsecond accuracy for the year 2242.
Additional precision would be overkill.
jribbens commented on Dec 15, 2008
jribbensmannequin
MannequinAuthor
More actions
A timedelta.toseconds method (or equivalent) makes no sense.
The number of seconds in a day is not fixed (due to leap seconds) and
relying on such a method would introduce subtle bugs.
You are misunderstanding what timedelta is. It is a fixed-length period
of time. It is stored as a number of (24x3600-second) days, seconds and
microseconds. There is no "start date" or "end date", so the concept of
leap seconds just does not apply.
AlexanderBelopolsky commented on Apr 21, 2010
AlexanderBelopolskymannequin
Mannequin
More actions
With bpo-2706 accepted, I think this issue can now be rejected because proposed td.tosecs() can now be spelled simply as td/timedelta(seconds=1).
The other RFE for a totimestamp() method is a duplicate of bpo-2736.
Blame Antoine. :) (See bpo-5788 and revision 76529.)
Shouldn't td.total_seconds() return Decimal? Maybe in py4k ...
Yes, that would have been nice.
I'm not sure that the Decimal type is well-established enough yet that it's okay to return Decimal instances from random unrelated modules, though. Maybe someday.
Activity
jribbens commentedon Mar 4, 2007
The datetime module is missing some important methods for interacting with timestamps (i.e. seconds since 1970-01-01T00:00:00).
There are methods to convert from a timestamp, i.e. date.fromtimestamp and datetime.fromtimestamp, but there are no methods to convert back.
In addition, timedelta has no method for returning the number of seconds it represents (i.e. days*86400+seconds+microseconds/1000000).
guettli commentedon Mar 22, 2007
Yes, that's true.
smontanaro commentedon Sep 2, 2007
There is no datetime.totimestamp because the range
of time represented by a datetime object far
exceeds the range of a normal int-based Unix
timestamp (roughly 1970-2038). Datetime objects
before the start of the Unix epoch would be
represented by negative numbers. As far as I
know, the common Unix library functions which
accept epoch times wouldn't know what to do
with a negative number.
That said, you stated these missing methods
were important. Can you offer some use
cases which would support that contention?
I personally don't think a argument for
symmetry would be a convincing use case and
that's the only one I can think of.
jribbens commentedon Sep 2, 2007
Almost everything you just said about time_t is wrong. time_t is signed,
and always has been (otherwise the 'end of time' for 32-bit time_t would
be 2106, not 2038). Also, time_t does not end at 2038 because nothing
says it must be 32 bits. Also, Python has 'long integers' which do not
overflow.
Also, I don't understand what you mean about use cases. The "use case"
is "dealing with anything which expects standard Unix time_t, for
example the Python standard library". The use case I have personally is
the program I was working on when I encountered the problem described in
this bug report. Also I think symmetry is a darn good argument. Why does
fromtimestamp exist if, as you claim, nobody uses time_t?
smontanaro commentedon Sep 2, 2007
Jon> Almost everything you just said about time_t is wrong. time_t is
Jon> signed, and always has been (otherwise the 'end of time' for 32-bit
Jon> time_t would be 2106, not 2038). Also, time_t does not end at 2038
Jon> because nothing says it must be 32 bits. Also, Python has 'long
Jon> integers' which do not overflow.
My apologies about goofing up on the signedness of time_t. What are you
going to do with a long integer that you can't do with a datetime object?
You clearly can't pass it directly to any Unix library functions which
expect time_t. Converting it can overflow.
What should datetime.datetime(9999, 1, 1).totimestamp() return? How would
you pass it to something which accepts a time_t? The fromtimestamp
functions work simply because the range of time_t is a proper subset of the
range of Python's datetime objects. Symmetry gets you little. In
situations where you need Unix timestamps and you know your datetime objects
are within the bounds representable by time_t, you can define a convenience
function:
This will, of course, fail if the year is too big or too small (and will
fail in platform-dependent ways if the underlying platform's range of
representable dates has different bounds than Unix does). Doing it without
resorting to calling time.mktime is also nontrivial. Under the covers the
datetime module currently uses platform functions to get time information
anyway. It doesn't do a lot of low-level time arithmethic itself.
Implementing fromtimestamp would require a fair amount of effort unless you
were willing to punt and just raise OverflowError for dates outside the
system's range.
Skip
tomster commentedon Nov 2, 2007
unless I'm missing something important this will do the trick quite
nicely:
>>> from datetime import datetime >>> datetime(2007, 12, 24, 20, 0).strftime("%s") '1198522800'For most imaginable use cases, where an epoch style time stamp is
required this should be enough.
HTH,
Tom
smontanaro commentedon Nov 2, 2007
Tom> unless I'm missing something important this will do the trick quite
Tom> nicely:
>>>> from datetime import datetime >>>> datetime(2007, 12, 24, 20, 0).strftime("%s") Tom> '1198522800'No fractions of a second...
Skip
jribbens commentedon Nov 2, 2007
If we're expecting floating-point, then everything you said earlier
about the limitations of ints was a bit redundant ;-)
smontanaro commentedon Nov 2, 2007
Yes, sorry. I responded to the mail without going back and reviewing the
entire thread. (It's been a couple months.) Note however that my example
to_timestamp() function converts the microseconds field to seconds and
include them in the result.
So, are we concluding that nothing needs to be added to the datetime module?
Skip
20 remaining items
srittau commentedon Dec 15, 2008
A timedelta.toseconds method (or equivalent) makes no sense. The number
of seconds in a day is not fixed (due to leap seconds) and relying on
such a method would introduce subtle bugs. The only way to find out the
number of seconds in a range of dates is if you have a concrete date range.
vstinner commentedon Dec 15, 2008
POSIX timestamp doesn't count leap seconds. It looks like the datetime
module is not aware of the leap seconds:
About my method: I finally prefer datetime/datetime or
datetime//datetime instead of a toseconds() method. And to convert a
timestamp to a timestamp: see my patch attached to issue bpo-2736.
vstinner commentedon Dec 15, 2008
I removed my ".toseconds() method" patch because I prefer division.
See issue bpo-2706 for divison, divmod, etc.
pitrou commentedon Dec 15, 2008
I also think totimestamp() on datetime objects would be useful, I've
missed it myself a couple of times. The return value should be similar
to that of time.time(), i.e. a float.
srittau commentedon Dec 15, 2008
Leap second handling is usually configurable. Default on Debian Linux
(but similar on RHEL and SuSE):
After doing "cp /usr/share/zoneinfo/right/Europe/Berlin /etc/localtime":
Also, NTP servers usually get this right. I don't think, Python should
promote a wrong date handling by default, even if it's convenient.
vstinner commentedon Dec 15, 2008
float is a source of many problems (rounding problems), especially for
huge values: float is unable to store correctly microseconds for big
values: see msg75426. A simple tuple (int, int) is simple and there is
no rounding/float limit.
pitrou commentedon Dec 15, 2008
What you say is "with 99500 days or more, the microsecond error is
bigger than 90%". It means that with epoch starting at 1970, you can
still return timestamps with a 1-2 microsecond accuracy for the year 2242.
Additional precision would be overkill.
jribbens commentedon Dec 15, 2008
You are misunderstanding what timedelta is. It is a fixed-length period
of time. It is stored as a number of (24x3600-second) days, seconds and
microseconds. There is no "start date" or "end date", so the concept of
leap seconds just does not apply.
AlexanderBelopolsky commentedon Apr 21, 2010
With bpo-2706 accepted, I think this issue can now be rejected because proposed td.tosecs() can now be spelled simply as td/timedelta(seconds=1).
The other RFE for a totimestamp() method is a duplicate of bpo-2736.
mdickinson commentedon Apr 21, 2010
Closing this as a duplicate of bpo-2736, as suggested. I'll combine the nosy lists.
(BTW, as well as the newly introduced division methods, td.tosecs already exists, except that it's spelt td.total_seconds.)
AlexanderBelopolsky commentedon Apr 21, 2010
On Wed, Apr 21, 2010 at 2:03 PM, Mark Dickinson <report@bugs.python.org> wrote:
..
Aggrrr! How did that slip in? :-)
86399999913600.0
Shouldn't td.total_seconds() return Decimal? Maybe in py4k ...
mdickinson commentedon Apr 21, 2010
Blame Antoine. :) (See bpo-5788 and revision 76529.)
Yes, that would have been nice.
I'm not sure that the Decimal type is well-established enough yet that it's okay to return Decimal instances from random unrelated modules, though. Maybe someday.