BUG: Fix Timestamp type checks to work with subclassed datetime (#25851)
- [x] closes #25851
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

PyDateTime_CheckExact is being used as a proxy for isinstance(obj, Timestamp) checks for performance reasons. However, if a subclass of the std datetime lib is being used, these checks are not sufficient to determine if an object is a Timestamp or not.

As discussed in #25746, any solution will be less performant than PyDateTime_CheckExact.  The best solution found was to use isinstance(obj, _Timestamp), and that is what I implemented here.

Of course, a few additional changes were necessary to be able to use that check.

Since asv isn't very good for cython code, I've done performance testing on all the modified functions by running them 10,000 times in a function, then timing that function in `%timeit`.  The results are below:
```
                       ----------- PR ---------         -------- Master -------
                        datetime     timestamp           datetime    timestamp
array_to_datetime        34.3 ms       34.5 ms            34.2 ms      34.5 ms
localize_pydatetime        15 ms       67.7 ms            15.2 ms      57.5 ms
normalize_date           12.7 ms         91 ms            12.8 ms      78.3 ms
Timedelta addition       1.05 ms         23 ms            1.04 ms      22.9 ms
Timestamp constructor    11.1 ms       9.85 ms            10.9 ms      9.79 ms
tz_localize                  N/A       63.7 ms                N/A      53.5 ms
normalize                    N/A       90.6 ms                N/A      78.5 ms
```
As you can see, some of the functions used with a `Timestamp` are affected, with a few unaffected.  Where there is an impact, it appears to be 15-20% less performant.

Note this fix also fixes (potentially) #25734, but if we want a separate test case for that issue I could modify my existing PR for that.