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.datetime() should accept a datetime.date as init parameter #66256
Comments
Currently (tested on py3.4): >>> from datetime import datetime, date
>>> d = datetime.now()
>>> date(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type datetime.datetime) IMO, it's like doing int(float), a truncation of some info. For example, this is what I want to happen: >>> d
datetime.datetime(2014, 7, 24, 11, 38, 44, 966613)
>>> date(d)
datetime.date(2014, 7, 24) |
There is already a spelling for that operation, and it is d.date(). I'm not sure that there is a strong enough argument for adding a second way to spell it, but I won't close this yet to see what other people think. Personally I don't think it has ever occurred to me to do date(datetime) (although I have wanted to pass a string to the constructor), and I've wanted the operation and found the 'date()' method more than once. |
+1 There is currently no obvious way to convert either date or datetime instance to date. The best solution I can think of is date(*x.timetuple()[:3]): >>> d = date.today()
>>> t = datetime.now()
>>> date(*d.timetuple()[:3])
datetime.date(2014, 7, 24)
>>> date(*t.timetuple()[:3])
datetime.date(2014, 7, 24) Certainly date(x) wins hands down over this atrocity. |
Was the title of this meant to be "datetime.date() should accept a datetime.datetime as init parameter" instead? That's what the example appears to be getting at. If so, -1. Datetime objects already have .date(), .time(), and .timetz() methods to extract, respectively, the date, naive time, and aware time portions of the datetime object. In the other direction, the datetime .combine() constructor builds a datetime object out of date and time components. As the docs say, "For any datetime object d, d == datetime.combine(d.date(), d.timetz())" Another way to spell this isn't needed.
some_datetime_object.date() is the obvious way to extract a date object from a datetime object. I don't know what it could mean to convert a date object to a date. That's pretty much exactly like asking how to convert an int object to an int. Huh? ;-) date and int objects are immutable, so a need to make a copy (if that's what is meant) rarely arises. |
Sorry if I was not clear enough about my use case. I often have to deal with functions that are designed to take either date or datetime object as an argument, but only use date components. In most cases this works automatically because datetime is a subclass of date. However, there are some annoying exceptions. For example, x > date(2001, 1, 1) will not work if x is a datetime instance. If in this example I write x.date() > date(2001, 1, 1) - I get the opposite problem - it won't work when x is a date instance. The "obvious" way would be date(x) > date(2001, 1, 1). Can you suggest anything better than date(*x.timetuple()[:3]) > date(2001, 1, 1) here? |
Another "solution" is date(2001, 1, 1).__lt__(x), but this is even uglier than the one with timetuple. |
Alexander, I don't see a need to make everything a one-liner. Dealing with a mix of dates and datetimes is easily sorted out with an def func(thedate):
if isinstance(thedate, datetime.datetime):
thedate = thedate.date()
# and now `thedate` is a bona fide datetime.date Or stick the two lines in a utility function. If you're determined to do it one line, because datetime is a subclass of date you could also use .combine() to force everything to class datetime.datetime in one line: _ZEROT = datetime.time()
def func(thedatetime):
thedatetime = datetime.combine(thedatetime, _ZEROT)
# and now `thedatetime` is a bona fide datetime.datetime |
It is not as mush about avoiding a one-liner as it is about duck-typing. IMO, dates and datetime objects are numbers in disguise. Many functions that are nominally numeric, can work with date/datetime/timedelta objects without modification. The fact that date/datetime do not accept their own instances often results in the need to branch on isinstance() or write a separate set of functions depending on whether dates are represented by numbers or by date instances. The example that I gave is one of many and the fact that you suggested using isinstance() in the solution is telling. My ideal design would be for date/datetime constructors to take one argument that can be a string, a 3+ elements iterable, or any object that has a .timetuple() method. The varargs variants can of course stay as syntactic sugar. |
El 24/07/14 a las 15:01, Tim Peters escibió:
Ah, I wasn't aware of the .date() method. I guess because it's more natural to me to do int(a_float) than So, unless anyody wants to pursue with this, I'll close the issue. Thanks! |
[David]
[Tim] [Facundo]
Marking as closed, rejected for the reasons listed and because making a function signature more complicated just isn't worth it. |
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: