Skip to content
Merged
4 changes: 0 additions & 4 deletions ci/code_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then
pandas.errors.UnsupportedFunctionCall \
pandas.test \
pandas.NaT \
pandas.Timestamp.date \
pandas.Timestamp.dst \
pandas.Timestamp.isocalendar \
pandas.Timestamp.isoweekday \
pandas.Timestamp.strptime \
pandas.Timestamp.time \
pandas.Timestamp.timetuple \
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ Datetimelike
^^^^^^^^^^^^
- :meth:`DatetimeIndex.map` with ``na_action="ignore"`` now works as expected. (:issue:`51644`)
- Bug in :func:`date_range` when ``freq`` was a :class:`DateOffset` with ``nanoseconds`` (:issue:`46877`)
- Bug in :meth:`Timestamp.date`, :meth:`Timestamp.isocalendar` were returning incorrect results for inputs outside those supported by the Python standard library's datetime module (:issue:`53668`)
- Bug in :meth:`Timestamp.round` with values close to the implementation bounds returning incorrect results instead of raising ``OutOfBoundsDatetime`` (:issue:`51494`)
- Bug in :meth:`arrays.DatetimeArray.map` and :meth:`DatetimeIndex.map`, where the supplied callable operated array-wise instead of element-wise (:issue:`51977`)
- Bug in constructing a :class:`Series` or :class:`DataFrame` from a datetime or timedelta scalar always inferring nanosecond resolution instead of inferring from the input (:issue:`52212`)
Expand Down
54 changes: 50 additions & 4 deletions pandas/_libs/tslibs/nattype.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,14 @@ class NaTType(_NaT):
Return the day of the week represented by the date.

Monday == 1 ... Sunday == 7.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.isoweekday()
7
""",
)
total_seconds = _make_nan_func(
Expand Down Expand Up @@ -506,13 +514,9 @@ class NaTType(_NaT):
""",
)
# _nat_methods
date = _make_nat_func("date", datetime.date.__doc__)

utctimetuple = _make_error_func("utctimetuple", datetime)
timetz = _make_error_func("timetz", datetime)
timetuple = _make_error_func("timetuple", datetime)
isocalendar = _make_error_func("isocalendar", datetime)
dst = _make_error_func("dst", datetime)
time = _make_error_func("time", datetime)
toordinal = _make_error_func("toordinal", datetime)
tzname = _make_error_func("tzname", datetime)
Expand All @@ -524,6 +528,48 @@ class NaTType(_NaT):
# ----------------------------------------------------------------------
# The remaining methods have docstrings copy/pasted from the analogous
# Timestamp methods.
isocalendar = _make_error_func(
"isocalendar",
"""
Return a named tuple containing ISO year, week number, and weekday.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.isocalendar()
datetime.IsoCalendarDate(year=2022, week=52, weekday=7)
"""
)
dst = _make_error_func(
"dst",
"""
Return the daylight saving time (DST) adjustment.

Examples
--------
>>> ts = pd.Timestamp('2000-06-01 00:00:00', tz='Europe/Brussels')
>>> ts
Timestamp('2000-06-01 00:00:00+0200', tz='Europe/Brussels')
>>> ts.dst()
datetime.timedelta(seconds=3600)
"""
)
date = _make_nat_func(
"date",
"""
Return date object with same year, month and day.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00.00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.date()
datetime.date(2023, 1, 1)
"""
)

ctime = _make_error_func(
"ctime",
Expand Down
69 changes: 69 additions & 0 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ from cpython.object cimport (

import_datetime()

import datetime as dt

from pandas._libs.tslibs cimport ccalendar
from pandas._libs.tslibs.base cimport ABCTimestamp

Expand Down Expand Up @@ -1531,6 +1533,64 @@ class Timestamp(_Timestamp):
) from err
return _dt.ctime()

def date(self):
"""
Return date object with same year, month and day.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00.00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.date()
datetime.date(2023, 1, 1)
"""
try:
_dt = dt.date(self.year, self.month, self.day)
except ValueError as err:
raise NotImplementedError(
"date not yet supported on Timestamps which "
"are outside the range of Python's standard library. "
) from err
return _dt

def dst(self):
"""
Return the daylight saving time (DST) adjustment.

Examples
--------
>>> ts = pd.Timestamp('2000-06-01 00:00:00', tz='Europe/Brussels')
>>> ts
Timestamp('2000-06-01 00:00:00+0200', tz='Europe/Brussels')
>>> ts.dst()
datetime.timedelta(seconds=3600)
"""
return super().dst()

def isocalendar(self):
"""
Return a named tuple containing ISO year, week number, and weekday.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.isocalendar()
datetime.IsoCalendarDate(year=2022, week=52, weekday=7)
"""
try:
_dt = datetime(self.year, self.month, self.day,
self.hour, self.minute, self.second,
self.microsecond, self.tzinfo, fold=self.fold)
except ValueError as err:
raise NotImplementedError(
"isocalendar not yet supported on Timestamps which "
"are outside the range of Python's standard library. "
) from err
return _dt.isocalendar()

# Issue 25016.
@classmethod
def strptime(cls, date_string, format):
Expand Down Expand Up @@ -2384,9 +2444,18 @@ default 'raise'
Return the day of the week represented by the date.

Monday == 1 ... Sunday == 7.

Examples
--------
>>> ts = pd.Timestamp('2023-01-01 10:00:00')
>>> ts
Timestamp('2023-01-01 10:00:00')
>>> ts.isoweekday()
7
"""
# same as super().isoweekday(), but that breaks because of how
# we have overridden year, see note in create_timestamp_from_ts

return self.weekday() + 1

def weekday(self):
Expand Down
16 changes: 14 additions & 2 deletions pandas/tests/scalar/timestamp/test_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1124,9 +1124,21 @@ def test_negative_dates():
# https://github.com/pandas-dev/pandas/issues/50787
ts = Timestamp("-2000-01-01")
msg = (
"^strftime not yet supported on Timestamps which are outside the range of "
" not yet supported on Timestamps which are outside the range of "
"Python's standard library. For now, please call the components you need "
r"\(such as `.year` and `.month`\) and construct your string from there.$"
)
with pytest.raises(NotImplementedError, match=msg):
func = "^strftime"
with pytest.raises(NotImplementedError, match=func + msg):
ts.strftime("%Y")

msg = (
" not yet supported on Timestamps which "
"are outside the range of Python's standard library. "
)
func = "^date"
with pytest.raises(NotImplementedError, match=func + msg):
ts.date()
func = "^isocalendar"
with pytest.raises(NotImplementedError, match=func + msg):
ts.isocalendar()