Skip to content

ENH/WIP: resolution inference in pd.to_datetime, DatetimeIndex #55901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 118 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
29e55c6
ENH: read_stata return non-nano
jbrockmendel Oct 23, 2023
d11a67c
GH ref
jbrockmendel Oct 23, 2023
dc53920
move whatsnew
jbrockmendel Jan 24, 2024
1bf05fa
remove outdated whatsnew
jbrockmendel Jan 26, 2024
4371b17
ENH: read_stata return non-nano
jbrockmendel Oct 23, 2023
9b37cd3
avoid Series.view
jbrockmendel Dec 1, 2023
04a9a7d
dont go through Series
jbrockmendel Dec 1, 2023
ef0de5a
TST: dt64 units
jbrockmendel Nov 30, 2023
8a0eab1
BUG: cut with non-nano
jbrockmendel Nov 21, 2023
1c00ecf
BUG: round with non-nanosecond raising OverflowError
jbrockmendel Nov 24, 2023
9b1a937
woops
jbrockmendel Nov 25, 2023
6f6936d
BUG: cut with non-nano
jbrockmendel Nov 21, 2023
d08f616
TST: parametrize tests over dt64 unit
jbrockmendel Nov 15, 2023
b66ea82
xfail non-nano
jbrockmendel Nov 15, 2023
a23e319
revert
jbrockmendel Nov 15, 2023
c9e93d6
BUG: mixed-type mixed-timezone/awareness
jbrockmendel Nov 1, 2023
ffcdd1a
commit so i can unstash something else i hope
jbrockmendel Nov 9, 2023
b1e587e
ENH: infer resolution in to_datetime, DatetimeIndex
jbrockmendel Nov 9, 2023
3b5251f
revert commented-out
jbrockmendel Nov 14, 2023
aea3846
revert commented-out
jbrockmendel Nov 14, 2023
cec8317
revert commented-out
jbrockmendel Nov 14, 2023
700e54b
remove commented-out
jbrockmendel Nov 14, 2023
a1253b0
remove comment
jbrockmendel Nov 14, 2023
38faad6
revert unnecessary
jbrockmendel Nov 14, 2023
543172e
revert unnecessary
jbrockmendel Nov 14, 2023
176717a
fix window tests
jbrockmendel Nov 14, 2023
4932942
Fix resample tests
jbrockmendel Nov 14, 2023
085a192
restore comment
jbrockmendel Nov 14, 2023
b8df281
revert unnecessary
jbrockmendel Nov 14, 2023
1cd91b4
remove no-longer necessary
jbrockmendel Nov 14, 2023
99cd581
revert no-longer-necessary
jbrockmendel Nov 14, 2023
237076f
revert no-longer-necessary
jbrockmendel Nov 14, 2023
5eb5e4e
update tests
jbrockmendel Nov 15, 2023
0f726be
revert no-longer-necessary
jbrockmendel Nov 15, 2023
15bfc7f
update tests
jbrockmendel Nov 15, 2023
01d3174
revert bits
jbrockmendel Nov 15, 2023
32efbe7
update tests
jbrockmendel Nov 16, 2023
55faffa
cleanup
jbrockmendel Nov 16, 2023
e4f8549
revert
jbrockmendel Nov 18, 2023
c0ea530
revert
jbrockmendel Nov 18, 2023
f342b5f
parametrize over unit
jbrockmendel Nov 19, 2023
c94fbe2
update tests
jbrockmendel Nov 19, 2023
0a649e0
update tests
jbrockmendel Nov 19, 2023
16d6c2d
revert no-longer-needed
jbrockmendel Nov 19, 2023
0c735b6
revert no-longer-necessary
jbrockmendel Nov 19, 2023
ff431f2
revert no-longer-necessary
jbrockmendel Nov 20, 2023
50bf675
revert no-longer-necessary
jbrockmendel Nov 20, 2023
93a3ee4
revert no-longer-necessary
jbrockmendel Nov 20, 2023
9c259d5
Revert no-longer-necessary
jbrockmendel Nov 20, 2023
d876178
update test
jbrockmendel Nov 21, 2023
589d0c5
update test
jbrockmendel Nov 21, 2023
63cdcec
simplify
jbrockmendel Nov 21, 2023
fc27070
update tests
jbrockmendel Nov 22, 2023
060aeb9
update tests
jbrockmendel Nov 22, 2023
9cd33e9
update tests
jbrockmendel Nov 23, 2023
aeebb39
revert no-longer-necessary
jbrockmendel Nov 24, 2023
40c09de
post-merge fixup
jbrockmendel Nov 24, 2023
fba3b79
revert no-longer-necessary
jbrockmendel Nov 24, 2023
6422cce
update tests
jbrockmendel Nov 25, 2023
553e90c
update test
jbrockmendel Nov 26, 2023
861ecb1
update tests
jbrockmendel Nov 27, 2023
eedb256
update tests
jbrockmendel Nov 28, 2023
5e24887
remove commented-out
jbrockmendel Nov 28, 2023
deb4a17
revert no-longer-necessary
jbrockmendel Nov 28, 2023
1e0e47a
as_unit->astype
jbrockmendel Nov 28, 2023
9576079
cleanup
jbrockmendel Nov 30, 2023
2b42758
merge fixup
jbrockmendel Dec 4, 2023
c195475
revert bit
jbrockmendel Dec 4, 2023
8e45823
revert no-longer-necessary, xfail
jbrockmendel Dec 9, 2023
f41da0a
update multithread test
jbrockmendel Dec 12, 2023
3737198
update tests
jbrockmendel Dec 12, 2023
8e2ff65
update doctest
jbrockmendel Dec 14, 2023
771d5f6
update tests
jbrockmendel Dec 14, 2023
fe8b50f
update doctests
jbrockmendel Dec 18, 2023
5bbe010
update tests
jbrockmendel Dec 18, 2023
c797270
update db tests
jbrockmendel Dec 18, 2023
ad54a8c
troubleshoot db tests
jbrockmendel Dec 18, 2023
0188ba9
update test
jbrockmendel Dec 19, 2023
7a8c3cf
troubleshoot sql tests
jbrockmendel Dec 20, 2023
c033795
update test
jbrockmendel Dec 21, 2023
c63d7de
update tests
jbrockmendel Jan 25, 2024
4ec85b0
mypy fixup
jbrockmendel Jan 26, 2024
5b3d769
Update test
jbrockmendel Feb 3, 2024
b0e9a25
kludge test
jbrockmendel Feb 21, 2024
5342f57
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 6, 2024
f71187a
update test
jbrockmendel Mar 7, 2024
0e702ea
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 12, 2024
d78531e
update for min-version tests
jbrockmendel Mar 12, 2024
ffe75dd
fix adbc check
jbrockmendel Mar 13, 2024
ad32d66
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 15, 2024
3178cab
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 21, 2024
0d3eab0
troubleshoot minimum version deps
jbrockmendel Mar 22, 2024
521c58a
troubleshoot
jbrockmendel Mar 22, 2024
6d8301b
troubleshoot
jbrockmendel Mar 22, 2024
003e9dd
troubleshoot
jbrockmendel Mar 22, 2024
2e80e9b
whatsnew
jbrockmendel Mar 22, 2024
b603b95
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 23, 2024
ee2f17e
update abdc-driver-postgresql minimum version
jbrockmendel Mar 23, 2024
9c9998e
update doctest
jbrockmendel Mar 25, 2024
9dc2328
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 25, 2024
dd74a1b
Merge branch 'main' of https://github.com/pandas-dev/pandas into enh-…
jbrockmendel Mar 26, 2024
94abaae
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Mar 26, 2024
44adf92
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Apr 24, 2024
a26cb9e
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Apr 29, 2024
2aae24f
fix doc example
jbrockmendel Apr 29, 2024
87dde3a
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel Apr 30, 2024
08c2f92
troubleshoot test_api_custom_dateparsing_error
jbrockmendel Apr 30, 2024
a10cae5
troubleshoot
jbrockmendel May 1, 2024
92c0df3
troubleshoot
jbrockmendel May 1, 2024
124c3d9
troubleshoot
jbrockmendel May 2, 2024
f921316
troubleshoot
jbrockmendel May 3, 2024
8c3bb89
troubleshoot
jbrockmendel May 3, 2024
5327bb6
troubleshoot
jbrockmendel May 3, 2024
f322e2c
update exp instead of object cast
jbrockmendel May 3, 2024
e2ed612
revert accidental
jbrockmendel May 3, 2024
4ff9b11
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel May 8, 2024
cd9b735
Merge branch 'main' into enh-array_to_datetime-inference
jbrockmendel May 21, 2024
4aa8513
simplify test
jbrockmendel May 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,69 @@ notable_bug_fix2
Backwards incompatible API changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. _whatsnew_300.api_breaking.datetime_resolution_inference:

Datetime resolution inference
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Converting a sequence of strings, ``datetime`` objects, or ``np.datetime64`` objects to
a ``datetime64`` dtype now performs inference on the appropriate resolution (AKA unit) for the output dtype. This affects :class:`Series`, :class:`DataFrame`, :class:`Index`, :class:`DatetimeIndex`, and :func:`to_datetime`.

Previously, these would always give nanosecond resolution:

.. code-block:: ipython

In [1]: dt = pd.Timestamp("2024-03-22 11:36").to_pydatetime()
In [2]: pd.to_datetime([dt]).dtype
Out[2]: dtype('<M8[ns]')
In [3]: pd.Index([dt]).dtype
Out[3]: dtype('<M8[ns]')
In [4]: pd.DatetimeIndex([dt]).dtype
Out[4]: dtype('<M8[ns]')
In [5]: pd.Series([dt]).dtype
Out[5]: dtype('<M8[ns]')

This now infers the unit microsecond unit "us" from the pydatetime object, matching the scalar :class:`Timestamp` behavior.

.. ipython:: python

In [1]: dt = pd.Timestamp("2024-03-22 11:36").to_pydatetime()
In [2]: pd.to_datetime([dt]).dtype
In [3]: pd.Index([dt]).dtype
In [4]: pd.DatetimeIndex([dt]).dtype
In [5]: pd.Series([dt]).dtype

Similar when passed a sequence of ``np.datetime64`` objects, the resolution of the passed objects will be retained (or for lower-than-second resolution, second resolution will be used).

When passing strings, the resolution will depend on the precision of the string, again matching the :class:`Timestamp` behavior. Previously:

.. code-block:: ipython

In [2]: pd.to_datetime(["2024-03-22 11:43:01"]).dtype
Out[2]: dtype('<M8[ns]')
In [3]: pd.to_datetime(["2024-03-22 11:43:01.002"]).dtype
Out[3]: dtype('<M8[ns]')
In [4]: pd.to_datetime(["2024-03-22 11:43:01.002003"]).dtype
Out[4]: dtype('<M8[ns]')
In [5]: pd.to_datetime(["2024-03-22 11:43:01.002003004"]).dtype
Out[5]: dtype('<M8[ns]')

The inferred resolution now matches that of the input strings:

.. ipython:: python

In [2]: pd.to_datetime(["2024-03-22 11:43:01"]).dtype
In [3]: pd.to_datetime(["2024-03-22 11:43:01.002"]).dtype
In [4]: pd.to_datetime(["2024-03-22 11:43:01.002003"]).dtype
In [5]: pd.to_datetime(["2024-03-22 11:43:01.002003004"]).dtype

In cases with mixed-resolution inputs, the highest resolution is used:

.. code-block:: ipython

In [2]: pd.to_datetime([pd.Timestamp("2024-03-22 11:43:01"), "2024-03-22 11:43:01.002"]).dtype
Out[2]: dtype('<M8[ns]')

.. _whatsnew_300.api_breaking.deps:

Increased minimum versions for dependencies
Expand Down
10 changes: 2 additions & 8 deletions pandas/_libs/lib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,12 @@ from pandas._libs.missing cimport (
is_null_datetime64,
is_null_timedelta64,
)
from pandas._libs.tslibs.conversion cimport (
_TSObject,
convert_to_tsobject,
)
from pandas._libs.tslibs.conversion cimport convert_to_tsobject
from pandas._libs.tslibs.nattype cimport (
NPY_NAT,
c_NaT as NaT,
checknull_with_nat,
)
from pandas._libs.tslibs.np_datetime cimport NPY_FR_ns
from pandas._libs.tslibs.offsets cimport is_offset_object
from pandas._libs.tslibs.period cimport is_period_object
from pandas._libs.tslibs.timedeltas cimport convert_to_timedelta64
Expand Down Expand Up @@ -2497,7 +2493,6 @@ def maybe_convert_objects(ndarray[object] objects,
ndarray[uint8_t] mask
Seen seen = Seen()
object val
_TSObject tsobj
float64_t fnan = NaN

if dtype_if_all_nat is not None:
Expand Down Expand Up @@ -2604,8 +2599,7 @@ def maybe_convert_objects(ndarray[object] objects,
else:
seen.datetime_ = True
try:
tsobj = convert_to_tsobject(val, None, None, 0, 0)
tsobj.ensure_reso(NPY_FR_ns)
convert_to_tsobject(val, None, None, 0, 0)
except OutOfBoundsDatetime:
# e.g. test_out_of_s_bounds_datetime64
seen.object_ = True
Expand Down
17 changes: 11 additions & 6 deletions pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ from pandas._libs.tslibs.conversion cimport (
get_datetime64_nanos,
parse_pydatetime,
)
from pandas._libs.tslibs.dtypes cimport npy_unit_to_abbrev
from pandas._libs.tslibs.dtypes cimport (
get_supported_reso,
npy_unit_to_abbrev,
)
from pandas._libs.tslibs.nattype cimport (
NPY_NAT,
c_nat_strings as nat_strings,
Expand Down Expand Up @@ -260,7 +263,7 @@ cpdef array_to_datetime(
bint dayfirst=False,
bint yearfirst=False,
bint utc=False,
NPY_DATETIMEUNIT creso=NPY_FR_ns,
NPY_DATETIMEUNIT creso=NPY_DATETIMEUNIT.NPY_FR_GENERIC,
str unit_for_numerics=None,
):
"""
Expand Down Expand Up @@ -288,8 +291,8 @@ cpdef array_to_datetime(
yearfirst parsing behavior when encountering datetime strings
utc : bool, default False
indicator whether the dates should be UTC
creso : NPY_DATETIMEUNIT, default NPY_FR_ns
Set to NPY_FR_GENERIC to infer a resolution.
creso : NPY_DATETIMEUNIT, default NPY_FR_GENERIC
If NPY_FR_GENERIC, conduct inference.
unit_for_numerics : str, default "ns"

Returns
Expand Down Expand Up @@ -389,7 +392,7 @@ cpdef array_to_datetime(
# GH#32264 np.str_ object
val = str(val)

if parse_today_now(val, &iresult[i], utc, creso):
if parse_today_now(val, &iresult[i], utc, creso, infer_reso=infer_reso):
# We can't _quite_ dispatch this to convert_str_to_tsobject
# bc there isn't a nice way to pass "utc"
item_reso = NPY_DATETIMEUNIT.NPY_FR_us
Expand Down Expand Up @@ -533,7 +536,9 @@ def array_to_datetime_with_tz(
if state.creso_ever_changed:
# We encountered mismatched resolutions, need to re-parse with
# the correct one.
return array_to_datetime_with_tz(values, tz=tz, creso=creso)
return array_to_datetime_with_tz(
values, tz=tz, dayfirst=dayfirst, yearfirst=yearfirst, creso=creso
)
elif creso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
# i.e. we never encountered anything non-NaT, default to "s". This
# ensures that insert and concat-like operations with NaT
Expand Down
6 changes: 3 additions & 3 deletions pandas/_libs/tslibs/strptime.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def array_strptime(
bint exact=True,
errors="raise",
bint utc=False,
NPY_DATETIMEUNIT creso=NPY_FR_ns,
NPY_DATETIMEUNIT creso=NPY_DATETIMEUNIT.NPY_FR_GENERIC,
):
"""
Calculates the datetime structs represented by the passed array of strings
Expand All @@ -365,7 +365,7 @@ def array_strptime(
fmt : string-like regex
exact : matches must be exact if True, search if False
errors : string specifying error handling, {'raise', 'coerce'}
creso : NPY_DATETIMEUNIT, default NPY_FR_ns
creso : NPY_DATETIMEUNIT, default NPY_FR_GENERIC
Set to NPY_FR_GENERIC to infer a resolution.
"""

Expand Down Expand Up @@ -712,7 +712,7 @@ cdef tzinfo _parse_with_format(
elif len(s) <= 6:
item_reso[0] = NPY_DATETIMEUNIT.NPY_FR_us
else:
item_reso[0] = NPY_DATETIMEUNIT.NPY_FR_ns
item_reso[0] = NPY_FR_ns
# Pad to always return nanoseconds
s += "0" * (9 - len(s))
us = int(s)
Expand Down
8 changes: 5 additions & 3 deletions pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,14 +346,15 @@ def unique(values):
array([2, 1])

>>> pd.unique(pd.Series([pd.Timestamp("20160101"), pd.Timestamp("20160101")]))
array(['2016-01-01T00:00:00.000000000'], dtype='datetime64[ns]')
array(['2016-01-01T00:00:00'], dtype='datetime64[s]')

>>> pd.unique(
... pd.Series(
... [
... pd.Timestamp("20160101", tz="US/Eastern"),
... pd.Timestamp("20160101", tz="US/Eastern"),
... ]
... ],
... dtype="M8[ns, US/Eastern]",
... )
... )
<DatetimeArray>
Expand All @@ -365,7 +366,8 @@ def unique(values):
... [
... pd.Timestamp("20160101", tz="US/Eastern"),
... pd.Timestamp("20160101", tz="US/Eastern"),
... ]
... ],
... dtype="M8[ns, US/Eastern]",
... )
... )
DatetimeIndex(['2016-01-01 00:00:00-05:00'],
Expand Down
12 changes: 6 additions & 6 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -1849,11 +1849,11 @@ def strftime(self, date_format: str) -> npt.NDArray[np.object_]:

>>> rng_tz.floor("2h", ambiguous=False)
DatetimeIndex(['2021-10-31 02:00:00+01:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)

>>> rng_tz.floor("2h", ambiguous=True)
DatetimeIndex(['2021-10-31 02:00:00+02:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)
"""

_floor_example = """>>> rng.floor('h')
Expand All @@ -1876,11 +1876,11 @@ def strftime(self, date_format: str) -> npt.NDArray[np.object_]:

>>> rng_tz.floor("2h", ambiguous=False)
DatetimeIndex(['2021-10-31 02:00:00+01:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)

>>> rng_tz.floor("2h", ambiguous=True)
DatetimeIndex(['2021-10-31 02:00:00+02:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)
"""

_ceil_example = """>>> rng.ceil('h')
Expand All @@ -1903,11 +1903,11 @@ def strftime(self, date_format: str) -> npt.NDArray[np.object_]:

>>> rng_tz.ceil("h", ambiguous=False)
DatetimeIndex(['2021-10-31 02:00:00+01:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)

>>> rng_tz.ceil("h", ambiguous=True)
DatetimeIndex(['2021-10-31 02:00:00+02:00'],
dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
dtype='datetime64[s, Europe/Amsterdam]', freq=None)
"""


Expand Down
35 changes: 18 additions & 17 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): # type: ignore[misc]
... )
<DatetimeArray>
['2023-01-01 00:00:00', '2023-01-02 00:00:00']
Length: 2, dtype: datetime64[ns]
Length: 2, dtype: datetime64[s]
"""

_typ = "datetimearray"
Expand Down Expand Up @@ -613,7 +613,7 @@ def tz(self) -> tzinfo | None:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.tz
datetime.timezone.utc

Expand Down Expand Up @@ -1047,7 +1047,7 @@ def tz_localize(
4 2018-10-28 02:30:00+01:00
5 2018-10-28 03:00:00+01:00
6 2018-10-28 03:30:00+01:00
dtype: datetime64[ns, CET]
dtype: datetime64[s, CET]

In some cases, inferring the DST is impossible. In such cases, you can
pass an ndarray to the ambiguous parameter to set the DST explicitly
Expand All @@ -1059,14 +1059,14 @@ def tz_localize(
0 2018-10-28 01:20:00+02:00
1 2018-10-28 02:36:00+02:00
2 2018-10-28 03:46:00+01:00
dtype: datetime64[ns, CET]
dtype: datetime64[s, CET]

If the DST transition causes nonexistent times, you can shift these
dates forward or backwards with a timedelta object or `'shift_forward'`
or `'shift_backwards'`.

>>> s = pd.to_datetime(pd.Series(['2015-03-29 02:30:00',
... '2015-03-29 03:30:00']))
... '2015-03-29 03:30:00'], dtype="M8[ns]"))
>>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_forward')
0 2015-03-29 03:00:00+02:00
1 2015-03-29 03:30:00+02:00
Expand Down Expand Up @@ -1427,7 +1427,7 @@ def time(self) -> npt.NDArray[np.object_]:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.time
0 10:00:00
1 11:00:00
Expand Down Expand Up @@ -1470,7 +1470,7 @@ def timetz(self) -> npt.NDArray[np.object_]:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.timetz
0 10:00:00+00:00
1 11:00:00+00:00
Expand Down Expand Up @@ -1512,7 +1512,7 @@ def date(self) -> npt.NDArray[np.object_]:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.date
0 2020-01-01
1 2020-02-01
Expand Down Expand Up @@ -1861,7 +1861,7 @@ def isocalendar(self) -> DataFrame:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.dayofyear
0 1
1 32
Expand Down Expand Up @@ -1897,7 +1897,7 @@ def isocalendar(self) -> DataFrame:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-04-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.quarter
0 1
1 2
Expand Down Expand Up @@ -1933,7 +1933,7 @@ def isocalendar(self) -> DataFrame:
>>> s
0 2020-01-01 10:00:00+00:00
1 2020-02-01 11:00:00+00:00
dtype: datetime64[ns, UTC]
dtype: datetime64[s, UTC]
>>> s.dt.daysinmonth
0 31
1 29
Expand Down Expand Up @@ -2372,9 +2372,9 @@ def _sequence_to_dt64(
data, copy = maybe_convert_dtype(data, copy, tz=tz)
data_dtype = getattr(data, "dtype", None)

if out_unit is None:
out_unit = "ns"
out_dtype = np.dtype(f"M8[{out_unit}]")
out_dtype = DT64NS_DTYPE
if out_unit is not None:
out_dtype = np.dtype(f"M8[{out_unit}]")

if data_dtype == object or is_string_dtype(data_dtype):
# TODO: We do not have tests specific to string-dtypes,
Expand All @@ -2400,7 +2400,7 @@ def _sequence_to_dt64(
dayfirst=dayfirst,
yearfirst=yearfirst,
allow_object=False,
out_unit=out_unit or "ns",
out_unit=out_unit,
)
copy = False
if tz and inferred_tz:
Expand Down Expand Up @@ -2508,7 +2508,7 @@ def objects_to_datetime64(
utc: bool = False,
errors: DateTimeErrorChoices = "raise",
allow_object: bool = False,
out_unit: str = "ns",
out_unit: str | None = None,
) -> tuple[np.ndarray, tzinfo | None]:
"""
Convert data to array of timestamps.
Expand All @@ -2524,7 +2524,8 @@ def objects_to_datetime64(
allow_object : bool
Whether to return an object-dtype ndarray instead of raising if the
data contains more than one timezone.
out_unit : str, default "ns"
out_unit : str or None, default None
None indicates we should do resolution inference.

Returns
-------
Expand Down
Loading
Loading