Skip to content
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

Closed
facundobatista opened this issue Jul 24, 2014 · 10 comments
Closed
Labels
type-feature A feature request or enhancement

Comments

@facundobatista
Copy link
Member

BPO 22058
Nosy @tim-one, @rhettinger, @facundobatista, @abalkin, @bitdancer

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 = None
closed_at = <Date 2014-07-25.19:23:26.825>
created_at = <Date 2014-07-24.14:41:32.891>
labels = ['type-feature']
title = 'datetime.datetime() should accept a datetime.date as init parameter'
updated_at = <Date 2014-07-25.19:23:26.824>
user = 'https://github.com/facundobatista'

bugs.python.org fields:

activity = <Date 2014-07-25.19:23:26.824>
actor = 'rhettinger'
assignee = 'none'
closed = True
closed_date = <Date 2014-07-25.19:23:26.825>
closer = 'rhettinger'
components = []
creation = <Date 2014-07-24.14:41:32.891>
creator = 'facundobatista'
dependencies = []
files = []
hgrepos = []
issue_num = 22058
keywords = []
message_count = 10.0
messages = ['223840', '223849', '223853', '223863', '223866', '223867', '223871', '223876', '223888', '223987']
nosy_count = 5.0
nosy_names = ['tim.peters', 'rhettinger', 'facundobatista', 'belopolsky', 'r.david.murray']
pr_nums = []
priority = 'normal'
resolution = 'rejected'
stage = 'needs patch'
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue22058'
versions = ['Python 3.5']

@facundobatista
Copy link
Member Author

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)

@facundobatista facundobatista changed the title datetime.datetime() should accept a datetime.date as constructor datetime.datetime() should accept a datetime.date as init parameter Jul 24, 2014
@bitdancer
Copy link
Member

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.

@abalkin
Copy link
Member

abalkin commented Jul 24, 2014

+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.

@abalkin abalkin added the type-feature A feature request or enhancement label Jul 24, 2014
@tim-one
Copy link
Member

tim-one commented Jul 24, 2014

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.

@abalkin
Copy link
Member

abalkin commented Jul 24, 2014

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?

@abalkin
Copy link
Member

abalkin commented Jul 24, 2014

Another "solution" is date(2001, 1, 1).__lt__(x), but this is even uglier than the one with timetuple.

@tim-one
Copy link
Member

tim-one commented Jul 24, 2014

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

@abalkin
Copy link
Member

abalkin commented Jul 24, 2014

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.

@facundobatista
Copy link
Member Author

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!

@rhettinger
Copy link
Contributor

[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.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

5 participants