Skip to content

Conversation

@pganssle
Copy link
Member

This seems like a convenience function that would be useful, particularly for passing in to parser.parse as default.

"""

dt = datetime.now(tzinfo)
return datetime.combine(dt.date(), time(0, tzinfo=tzinfo))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Responding to this comment by @jbrockmendel:

+1 for today(tzinfo), but I'm very wary of implementing behavior that differs from same-named stdlib behavior. btw:

>>> tz = pytz.timezone('US/Pacific')
>>> pd.Timestamp.today(tz)
Timestamp('2017-10-14 17:19:04.081315-0700', tz='US/Pacific')

My reason for calling it today was because, frankly, I think that this is close to datetime.datetime.today() should do, and I think it violates principle of least surprise to find that datetime.today() is basically just an alias for datetime.now(). That said, the name overloading is my main concern about this function.

I think there are a few reasonable ways forward:

  1. Leave as is because this is what datetime.today() should have been and people are more likely to be shocked that datetime.datetime.today() does something else than that dateutil.utils.today() does what it does.
  2. Change the signature of this so that utils.today() takes an optional time argument in addition to an optional tzinfo argument. This makes it more clear that what it does is give you "today at this time, defaulting to midnight". The reason I don't like this is that there could be a conflict between time (which may have a tzinfo of its own) and tzinfo, and also the interface isn't nearly as clean.
  3. Change the name to something like today_midnight() or today_datetime() or something.

I think I'm inclined to leave it as is, considering pendulum has a similar real distinction between its now and today behavior:

>>> import pendulum
>>> print(pendulum.now())
2017-10-15T17:30:33.887480-04:00
>>>> print(pendulum.today())
2017-10-15T00:00:00-04:00

@pganssle pganssle mentioned this pull request Oct 15, 2017
package_data={"dateutil.zoneinfo": ["dateutil-zoneinfo.tar.gz"]},
zip_safe=True,
requires=["six"],
tests_require=["freezegun"],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should note that I'm not sure that this is the most foolproof way of installing test-specific dependencies, as the only thing that cares about this particular line is, AFAIK, python setup.py test, and if we're going to move to pytest, we'll either want our own setup.py test runner that uses pytest, and/or we should have a separate script that declares and installs the test dependencies independent of python setup.py test. Not sure what most people do.

@jbrockmendel
Copy link
Contributor

I'm inclined to agree about the ideal behavior of datetime.datetime.today, but pushing back against that is like fighting the tides.

that datetime.today() is basically just an alias for datetime.now()

Note there is a small difference: now will accept a tzinfo argument.

If this is intended to be user-facing, then the name should avoid adding to the morass here. If it is intended to be internal, I would be fine with _today.

@pganssle
Copy link
Member Author

@jbrockmendel It's definitely intended to be external-facing.

I honestly don't see a big problem with diverging from datetime.datetime.today - datetime.datetime.today is an alternate constructor for datetime. This is a utility that gives you today at midnight. To me, the main problem with the name is mostly that it doesn't convey that it's going to give you a datetime back just from the name. I think it will be far less confusing than Python's current behavior.

Note there is a small difference: now will accept a tzinfo argument.

Wow, I didn't even realize this. So it's basically a worse version of now(). I don't think we should be emulating this API at all.

@jbrockmendel
Copy link
Contributor

The downside of name overlap strikes me as much bigger than the upside from a one-liner. Since we'll be stuck with the API indefinitely, a distinct name seems like the way to go. That said, its not worth arguing about, so do your thing.

@pganssle
Copy link
Member Author

I don't really think there's a serious downside from the name overlap. It's not even possible to import datetime.datetime.today as a bare function, so the semantics of a bare function and an alternate constructor are completely different. The real problem I see is that the semantics of the two would be reversed - the default value for unspecified time components of datetime is 0, which is why it's bizarre that datetime.today (which you would expect to be the equivalent of calling date.today() and combining it with an empty time component) is a shittier version of datetime.now(), whereas a bare function called today() seems like it should return a date.

I'm really torn between:

  • today() - seems like the most natural and most people will probably intuitively get what it does
  • today_datetime() - This is explicit about what it does, but more verbose than I prefer.
  • datetime_today() - Again, explicit, but this actually might get confused for datetime.today()

So far I'm still liking today() most. If I've learned anything from fielding issues on this repo and on the SO python-dateutil tag for a few years is that people don't read documentation, and they'll be very confused if something doesn't do what it seems like it would do. People will probably not complain if today() returns a datetime, because I really get the impression that people don't use the date class much at all and are expecting full datetime objects every time. They would also likely complain if today() returned what datetime.today() returns, since it's confusing and counter-intuitive. Likely they wouldn't complain about today_datetime(), but they'd be less likely to use it, because anything that's not a super concise one-liner seems not worth it to most people I guess.

@pganssle
Copy link
Member Author

OK, I'm going to go ahead and merge this. I doubt anyone will be too confused that today() returns a datetime (very few people care about the difference between date and datetime), and I could always justify it a bit with an at keyword argument that lets you specify the time as well.

@pganssle pganssle merged commit 2587340 into dateutil:master Oct 25, 2017
@pganssle pganssle mentioned this pull request Mar 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants