CI: Test Python 3.12
- [ ] xref #53665  (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.

For those interested, we have
```208 failed, 172066 passed, 18996 skipped, 982 xfailed, 84 xpassed, 56 warnings in 2448.38s (0:40:48) =```

Not bad, given most are parametrized, but definitely much more than last year 😭 . I pushed up a fix to use `timezone.utc`. I think `datetime.UTC` is > PY311 Thanks for updating this, and sorry for losing track of this PR.

I have the Docker image for Python 3.12 set up on my laptop, so I'll try to get some debugging in tomorrow for the Index failures, unless you beat me to it again :). Looks like the major change is 

> [slice](https://docs.python.org/3.12/library/functions.html#slice) objects are now hashable, allowing them to be used as  dict keys and set items. (Contributed by Will Bradshaw, Furkan Onder, and Raymond Hettinger in [gh-101264](https://github.com/python/cpython/issues/101264).) Down to 4 tests
```
FAILED pandas/tests/computation/test_eval.py::TestEval::test_true_false_logic - DeprecationWarning: Bitwise inversion '~' on bool is deprecated. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
FAILED pandas/tests/frame/indexing/test_where.py::TestDataFrameIndexingWhere::test_where_invalid - DeprecationWarning: Bitwise inversion '~' on bool is deprecated. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
FAILED pandas/tests/series/indexing/test_getitem.py::test_getitem_generator - AssertionError: Series are different

Series length are different
[left]:  0, Index([], dtype='object')
[right]: 14, Index(['1bZFplgxJt', 'dgf6MOzmcc', 'nXA7LxB4pD', '7xialahw4M', 'eHSMzF5vTv',
       'ohno0T7Zu6', 'sK2uiqyfCh', 'ccmUonUyaI', 'KNYdKnS7IO', 'jQ9UjUVpex',
       'NGazj6cYBr', 'XHqmZevyyF', 'SQXHWlGTY5', 'ZmyLvG2mLO'],
      dtype='object')
FAILED pandas/tests/tseries/offsets/test_year.py::test_add_out_of_pydatetime_range
```

I think I regressed one of the indexing tests in my fixes. This should be ready now.

cc @jbrockmendel @phofl for indexing changes 

Not sure who to ping for eval/sql changes.