msg223840 - (view) |
Author: Facundo Batista (facundobatista) *  |
Date: 2014-07-24 14:41 |
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)
|
msg223849 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2014-07-24 15:33 |
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.
|
msg223853 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2014-07-24 15:52 |
+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.
|
msg223863 - (view) |
Author: Tim Peters (tim.peters) *  |
Date: 2014-07-24 18:01 |
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.
> There is currently no obvious way to convert either date
> or datetime instance to date.
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.
|
msg223866 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2014-07-24 18:29 |
> some_datetime_object.date() is the obvious way to extract a
> date object from a datetime object.
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?
|
msg223867 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2014-07-24 18:32 |
Another "solution" is date(2001, 1, 1).__lt__(x), but this is even uglier than the one with timetuple.
|
msg223871 - (view) |
Author: Tim Peters (tim.peters) *  |
Date: 2014-07-24 19:01 |
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 `if` statement, like
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
|
msg223876 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2014-07-24 19:26 |
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.
|
msg223888 - (view) |
Author: Facundo Batista (facundobatista) *  |
Date: 2014-07-24 20:12 |
El 24/07/14 a las 15:01, Tim Peters escibió:
> "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
Ah, I wasn't aware of the .date() method.
I guess because it's more natural to me to do int(a_float) than
a_float.integer().
So, unless anyody wants to pursue with this, I'll close the issue.
Thanks!
|
msg223987 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2014-07-25 19:23 |
[David]
> There is already a spelling for that operation, and it is d.date()
[Tim]
Alexander, I don't see a need to make everything a one-liner
[Facundo]
> So, unless anyody wants to pursue with this, I'll close the issue.
Marking as closed, rejected for the reasons listed and because making a function signature more complicated just isn't worth it.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:06 | admin | set | github: 66256 |
2014-07-25 19:23:26 | rhettinger | set | status: open -> closed
nosy:
+ rhettinger messages:
+ msg223987
resolution: rejected |
2014-07-24 20:12:32 | facundobatista | set | messages:
+ msg223888 |
2014-07-24 19:26:13 | belopolsky | set | messages:
+ msg223876 |
2014-07-24 19:01:33 | tim.peters | set | messages:
+ msg223871 |
2014-07-24 18:32:54 | belopolsky | set | messages:
+ msg223867 |
2014-07-24 18:29:29 | belopolsky | set | messages:
+ msg223866 |
2014-07-24 18:01:46 | tim.peters | set | nosy:
+ tim.peters messages:
+ msg223863
|
2014-07-24 15:52:22 | belopolsky | set | type: enhancement messages:
+ msg223853 stage: needs patch |
2014-07-24 15:33:15 | r.david.murray | set | nosy:
+ r.david.murray, belopolsky messages:
+ msg223849
|
2014-07-24 15:02:51 | facundobatista | set | title: datetime.datetime() should accept a datetime.date as constructor -> datetime.datetime() should accept a datetime.date as init parameter |
2014-07-24 14:41:32 | facundobatista | create | |