Fix Series[timedelta64]+DatetimeIndex[tz] bugs
State: closed

ser + index lost timezone
index + ser retained timezone but returned a DatetimeIndex

- [x] closes #13905
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Labels:
name: Bug
name: Datetime
description: Datetime data dtype
name: Timedelta
description: Timedelta data type
name: Timezones
description: Timezone data dtype

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=h1) Report
> Merging [#18884](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/c19bdc98fa3f856e2e6b3495bbab88b587801987?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `93.33%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/18884/graphs/tree.svg?width=650&height=150&token=eZ4WkYLtcO&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #18884      +/-   ##
==========================================
+ Coverage   91.57%   91.57%   +<.01%     
==========================================
  Files         150      150              
  Lines       48941    48948       +7     
==========================================
+ Hits        44817    44824       +7     
  Misses       4124     4124
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.93% <93.33%> (ø)` | :arrow_up: |
| #single | `41.75% <26.66%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/ops.py](https://codecov.io/gh/pandas-dev/pandas/pull/18884/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvb3BzLnB5) | `90.41% <100%> (+0.17%)` | :arrow_up: |
| [pandas/core/indexes/datetimelike.py](https://codecov.io/gh/pandas-dev/pandas/pull/18884/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZWxpa2UucHk=) | `97.08% <100%> (+0.02%)` | :arrow_up: |
| [pandas/core/indexes/datetimes.py](https://codecov.io/gh/pandas-dev/pandas/pull/18884/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZXMucHk=) | `95.17% <50%> (-0.28%)` | :arrow_down: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/18884/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `84.95% <0%> (+0.21%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=footer). Last update [c19bdc9...190197c](https://codecov.io/gh/pandas-dev/pandas/pull/18884?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

> well I don't want this here. put it where the other conversions are. that can be reactored at some point if its worthile.

I'm in the process of implementing this, but please reconsider.

Moving this into `_TimeOp` requires implementing logic to figure out what the output `dtype` is.  While this is doable, it is entirely unnecessary because it is essentially re-implementing (worse) the logic in the `TimedeltaIndex` operation.

The most recent attempt to kludge this into TimeOp still got the dtypes wrong.  The way presented is the right way to do this.
then let’s refactor this first
i don’t want to add a sub optimal soln which will then be removed 
Huh?  The change here is in the direction of the long-term solution, is not going to be removed, is not sub-optimal. 
Pls reopen.
Got the requested (but much worse) version working.  Please reopen.
ok let's see what you have.
> ok let's see what you have.

Pushed yesterday, looks like CI just finished.
Without using `res_name = _get_series_op_result_name(left, right)` we get failures in `tests.series.test_operators`, so I'm re-implementing it.

- `name` --> `res_name` to avoid ambiguity with the _other_ `name` variable floating around the nested namespaces/closures.
- Single, obvious-upon-inspection source of truth for how Series op result names are chosen
- <b>Most important</b> Robust to whatever wacky type conversions are done in `_TimeOp`.
@jbrockmendel FYI I cancelled a couple of your builds on travis. trying to get 0.22 out. most of these PR's have comments anyhow.
> FYI I cancelled a couple of your builds on travis. trying to get 0.22 out. most of these PR's have comments anyhow.

Sounds good.  I'll flag any comments that need clarification.

BTW appveyor usually seems to be the constraining factor when the pipeline gets clogged.  In cases where I screw up is there a way to cancel build for my own PRs there?
when you push again appveyor (and travis) both cancel the previous. so it doesn't matter really. travis does it as soon as you push, while appveyor won't cancel until it actually runs (so it looks like its taking longer).
Just pushed fixes, including for #18989.  You may need to cancel the build again.
Repush or hang tight?
all good now
go ahead and repush
rebase and push again, fixed some hanging by Travis CI
This should be ready, is orthogonal to #19024.
thanks!