diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index be7a07dface0a..4b7c2c0baa52e 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -694,6 +694,7 @@ Datetimelike - Bug in :attr:`is_year_start` where a DateTimeIndex constructed via a date_range with frequency 'MS' wouldn't have the correct year or quarter start attributes (:issue:`57377`) - Bug in :class:`DataFrame` raising ``ValueError`` when ``dtype`` is ``timedelta64`` and ``data`` is a list containing ``None`` (:issue:`60064`) - Bug in :class:`Timestamp` constructor failing to raise when ``tz=None`` is explicitly specified in conjunction with timezone-aware ``tzinfo`` or data (:issue:`48688`) +- Bug in :class:`Timestamp` constructor failing to raise when given a ``np.datetime64`` object with non-standard unit (:issue:`25611`) - Bug in :func:`date_range` where the last valid timestamp would sometimes not be produced (:issue:`56134`) - Bug in :func:`date_range` where using a negative frequency value would not include all points between the start and end values (:issue:`56147`) - Bug in :func:`tseries.api.guess_datetime_format` would fail to infer time format when "%Y" == "%H%M" (:issue:`57452`) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 45552108f8c15..2a080bcb19ae9 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -5,6 +5,7 @@ import numpy as np cimport numpy as cnp from libc.math cimport log10 from numpy cimport ( + PyDatetimeScalarObject, float64_t, int32_t, int64_t, @@ -358,6 +359,7 @@ cdef _TSObject convert_to_tsobject(object ts, tzinfo tz, str unit, cdef: _TSObject obj NPY_DATETIMEUNIT reso + int64_t num obj = _TSObject() @@ -367,6 +369,13 @@ cdef _TSObject convert_to_tsobject(object ts, tzinfo tz, str unit, if checknull_with_nat_and_na(ts): obj.value = NPY_NAT elif cnp.is_datetime64_object(ts): + num = (ts).obmeta.num + if num != 1: + raise ValueError( + # GH#25611 + "np.datetime64 objects with units containing a multiplier are " + "not supported" + ) reso = get_supported_reso(get_datetime64_unit(ts)) obj.creso = reso obj.value = get_datetime64_nanos(ts, reso) diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index 2c97c4a32e0aa..09ca5a71503ad 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -478,6 +478,13 @@ def test_now_today_unit(self, method): class TestTimestampConstructors: + def test_disallow_dt64_with_weird_unit(self): + # GH#25611 + dt64 = np.datetime64(1, "500m") + msg = "np.datetime64 objects with units containing a multiplier" + with pytest.raises(ValueError, match=msg): + Timestamp(dt64) + def test_weekday_but_no_day_raises(self): # GH#52659 msg = "Parsing datetimes with weekday but no day information is not supported"