API: make Day preserve time-of-day across DST transitions
State: closed

- [x] closes #41943 (Replace xxxx with the GitHub issue number)
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

Updated version of #51874.

I'm trying to find things to split off of this or do as bite-size deprecations.  Not much optimism on those fronts.  I expect we'll need to do this all-at-once in 3.0 or as a giant deprecation in 2.x with a future option.

<b>update:</b> ideas for bits to split off or deprecate
- `Day.__truediv__` and multiplication by non-int could be deprecated, this shouldn't be too painful for users since i doubt anyone actually uses it
- deprecate allowing `Timedelta(day_obj)`.  Again should be rare
- deprecate allowing Day objects for freq in TDI constructor

Labels:
name: Frequency
description: DateOffsets
name: Timezones
description: Timezone data dtype
name: Stale

Comments:
This pull request is stale because it has been open for thirty days with no activity. Please [update](https://pandas.pydata.org/pandas-docs/stable/development/contributing.html#updating-your-pull-request) and respond to this comment if you're still interested in working on this.
> I'm trying to find things to split off of this or do as bite-size deprecations. Not much optimism on those fronts. I expect we'll need to do this all-at-once in 3.0 or as a giant deprecation in 2.x with a future option.

all at once sounds fine to be honest, I'd consider it a bug that
```python
In [44]: pd.Series([datetime(2020, 10, 25)]).dt.tz_localize('Europe/London') + pd.tseries.offsets.Day(1)
Out[44]:
0   2020-10-25 23:00:00+00:00
dtype: datetime64[ns, Europe/London]
```
happens

Please do ping when it's ready for review (looks like there's lots of conflicts atm)
@jorisvandenbossche can i get you to take a look here pre-merge (which is not imminent)?
> Are the conversions of Day to hours needed for this change to be less breaking?

IIRC they were for either a) cases where we went DatetimeIndex->TimedeltaIndex (e.g. subtracting a scalar from DatetimeIndex) or b) to allow users to continue to pass freq="2D" to TimedeltaIndex-like functions.  The latter could be disallowed either directly or via deprecation.

I'll take another pass and see if any of these usages can be removed.
On last week's dev call we discussed an option to allow TimedeltaIndex.freq to be a Day even though that isn't a Tick, the idea being that this would reduce churn for users.  I've been working on a branch that does that, but still have 76 tests failing.  Most of these seem to stem from the fact that Day(1) no longer compares as equal to Hour(24) (or Second(86400) or [...]).

e.g. in `pandas/tests/resample/test_period_index.py::TestPeriodIndex::test_resample_with_offset` (in main and the branch) result.index.freq is `Day(1)` while expected.index.freq is `Hour(24)`.  `tm.assert_series_equal(result, expected)` passes in main because they compare as equal.

One option is to patch the affected tests to say "close enough".  I need to look more closely to determine if I'm comfortable with that. <b>Update</b> Very comfortable.

There's also a handful of resample tests (test_resample_origin_with_day_freq_on_dst) that look materially different that I don't have a good handle on.
Closing in favor of #61985.