diff --git a/doc/source/whatsnew/v1.6.0.rst b/doc/source/whatsnew/v1.6.0.rst index 566e3d7c66b79..7237abf351866 100644 --- a/doc/source/whatsnew/v1.6.0.rst +++ b/doc/source/whatsnew/v1.6.0.rst @@ -115,9 +115,11 @@ See :ref:`install.dependencies` and :ref:`install.optional_dependencies` for mor Other API changes ^^^^^^^^^^^^^^^^^ +- Passing ``nanoseconds`` greater than 999 or less than 0 in :class:`Timestamp` now raises a ``ValueError`` (:issue:`48538`, :issue:`48255`) - :func:`read_csv`: specifying an incorrect number of columns with ``index_col`` of now raises ``ParserError`` instead of ``IndexError`` when using the c parser. - + .. --------------------------------------------------------------------------- .. _whatsnew_160.deprecations: diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 07c6e32028942..46e4c24d1fd6b 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -1692,7 +1692,13 @@ class Timestamp(_Timestamp): ) # Once this deprecation is enforced, we can do # return Timestamp(ts_input).tz_localize(tzobj) - ts = convert_to_tsobject(ts_input, tzobj, unit, 0, 0, nanosecond or 0) + + if nanosecond is None: + nanosecond = 0 + elif not (999 >= nanosecond >= 0): + raise ValueError("nanosecond must be in 0..999") + + ts = convert_to_tsobject(ts_input, tzobj, unit, 0, 0, nanosecond) if ts.value == NPY_NAT: return NaT diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index 7b3647dc6cbef..58150fdce8503 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -677,3 +677,10 @@ def test_constructor_missing_keyword(kwargs): with pytest.raises(TypeError, match=msg): Timestamp(**kwargs) + + +@pytest.mark.parametrize("nano", [-1, 1000]) +def test_timestamp_nano_range(nano): + # GH 48255 + with pytest.raises(ValueError, match="nanosecond must be in 0..999"): + Timestamp(year=2022, month=1, day=1, nanosecond=nano)