Skip to content

Commit 723141d

Browse files
authored
PERF: put some Timetamp methods in _Timestamp (#35036)
1 parent ff2b70c commit 723141d

File tree

2 files changed

+151
-144
lines changed

2 files changed

+151
-144
lines changed

pandas/_libs/tslibs/timestamps.pxd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ cdef class _Timestamp(ABCTimestamp):
1616
int64_t value, nanosecond
1717
object freq
1818

19-
cpdef bint _get_start_end_field(self, str field)
20-
cpdef _get_date_name_field(self, object field, object locale)
19+
cdef bint _get_start_end_field(self, str field)
20+
cdef _get_date_name_field(self, str field, object locale)
2121
cdef int64_t _maybe_convert_value_to_local(self)
2222
cpdef to_datetime64(self)
2323
cdef _assert_tzawareness_compat(_Timestamp self, datetime other)

pandas/_libs/tslibs/timestamps.pyx

Lines changed: 149 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@ cdef class _Timestamp(ABCTimestamp):
441441

442442
return NotImplemented
443443

444+
# -----------------------------------------------------------------
445+
444446
cdef int64_t _maybe_convert_value_to_local(self):
445447
"""Convert UTC i8 value to local i8 value if tz exists"""
446448
cdef:
@@ -450,7 +452,7 @@ cdef class _Timestamp(ABCTimestamp):
450452
val = tz_convert_single(self.value, UTC, self.tz)
451453
return val
452454

453-
cpdef bint _get_start_end_field(self, str field):
455+
cdef bint _get_start_end_field(self, str field):
454456
cdef:
455457
int64_t val
456458
dict kwds
@@ -471,7 +473,67 @@ cdef class _Timestamp(ABCTimestamp):
471473
field, freqstr, month_kw)
472474
return out[0]
473475

474-
cpdef _get_date_name_field(self, object field, object locale):
476+
@property
477+
def is_month_start(self) -> bool:
478+
"""
479+
Return True if date is first day of month.
480+
"""
481+
if self.freq is None:
482+
# fast-path for non-business frequencies
483+
return self.day == 1
484+
return self._get_start_end_field("is_month_start")
485+
486+
@property
487+
def is_month_end(self) -> bool:
488+
"""
489+
Return True if date is last day of month.
490+
"""
491+
if self.freq is None:
492+
# fast-path for non-business frequencies
493+
return self.day == self.days_in_month
494+
return self._get_start_end_field("is_month_end")
495+
496+
@property
497+
def is_quarter_start(self) -> bool:
498+
"""
499+
Return True if date is first day of the quarter.
500+
"""
501+
if self.freq is None:
502+
# fast-path for non-business frequencies
503+
return self.day == 1 and self.month % 3 == 1
504+
return self._get_start_end_field("is_quarter_start")
505+
506+
@property
507+
def is_quarter_end(self) -> bool:
508+
"""
509+
Return True if date is last day of the quarter.
510+
"""
511+
if self.freq is None:
512+
# fast-path for non-business frequencies
513+
return (self.month % 3) == 0 and self.day == self.days_in_month
514+
return self._get_start_end_field("is_quarter_end")
515+
516+
@property
517+
def is_year_start(self) -> bool:
518+
"""
519+
Return True if date is first day of the year.
520+
"""
521+
if self.freq is None:
522+
# fast-path for non-business frequencies
523+
return self.day == self.month == 1
524+
return self._get_start_end_field("is_year_start")
525+
526+
@property
527+
def is_year_end(self) -> bool:
528+
"""
529+
Return True if date is last day of the year.
530+
"""
531+
if self.freq is None:
532+
# fast-path for non-business frequencies
533+
return self.month == 12 and self.day == 31
534+
return self._get_start_end_field("is_year_end")
535+
536+
cdef _get_date_name_field(self, str field, object locale):
475537
cdef:
476538
int64_t val
477539
object[:] out
@@ -481,6 +543,85 @@ cdef class _Timestamp(ABCTimestamp):
481543
field, locale=locale)
482544
return out[0]
483545

546+
def day_name(self, locale=None) -> str:
547+
"""
548+
Return the day name of the Timestamp with specified locale.
549+
550+
Parameters
551+
----------
552+
locale : str, default None (English locale)
553+
Locale determining the language in which to return the day name.
554+
555+
Returns
556+
-------
557+
day_name : string
558+
559+
.. versionadded:: 0.23.0
560+
"""
561+
return self._get_date_name_field("day_name", locale)
562+
563+
def month_name(self, locale=None) -> str:
564+
"""
565+
Return the month name of the Timestamp with specified locale.
566+
567+
Parameters
568+
----------
569+
locale : str, default None (English locale)
570+
Locale determining the language in which to return the month name.
571+
572+
Returns
573+
-------
574+
month_name : string
575+
576+
.. versionadded:: 0.23.0
577+
"""
578+
return self._get_date_name_field("month_name", locale)
579+
580+
@property
581+
def is_leap_year(self) -> bool:
582+
"""
583+
Return True if year is a leap year.
584+
"""
585+
return bool(ccalendar.is_leapyear(self.year))
586+
587+
@property
588+
def dayofweek(self) -> int:
589+
"""
590+
Return day of the week.
591+
"""
592+
return self.weekday()
593+
594+
@property
595+
def dayofyear(self) -> int:
596+
"""
597+
Return the day of the year.
598+
"""
599+
return ccalendar.get_day_of_year(self.year, self.month, self.day)
600+
601+
@property
602+
def quarter(self) -> int:
603+
"""
604+
Return the quarter of the year.
605+
"""
606+
return ((self.month - 1) // 3) + 1
607+
608+
@property
609+
def week(self) -> int:
610+
"""
611+
Return the week number of the year.
612+
"""
613+
return ccalendar.get_week_of_year(self.year, self.month, self.day)
614+
615+
@property
616+
def days_in_month(self) -> int:
617+
"""
618+
Return the number of days in the month.
619+
"""
620+
return ccalendar.get_days_in_month(self.year, self.month)
621+
622+
# -----------------------------------------------------------------
623+
# Rendering Methods
624+
484625
@property
485626
def _repr_base(self) -> str:
486627
return f"{self._date_repr} {self._time_repr}"
@@ -514,6 +655,8 @@ cdef class _Timestamp(ABCTimestamp):
514655
return self._date_repr
515656
return self._repr_base
516657

658+
# -----------------------------------------------------------------
659+
517660
@property
518661
def asm8(self) -> np.datetime64:
519662
"""
@@ -1040,153 +1183,13 @@ timedelta}, default 'raise'
10401183

10411184
return Period(self, freq=freq)
10421185

1043-
@property
1044-
def dayofweek(self) -> int:
1045-
"""
1046-
Return day of the week.
1047-
"""
1048-
return self.weekday()
1049-
1050-
def day_name(self, locale=None) -> str:
1051-
"""
1052-
Return the day name of the Timestamp with specified locale.
1053-
1054-
Parameters
1055-
----------
1056-
locale : str, default None (English locale)
1057-
Locale determining the language in which to return the day name.
1058-
1059-
Returns
1060-
-------
1061-
day_name : string
1062-
1063-
.. versionadded:: 0.23.0
1064-
"""
1065-
return self._get_date_name_field('day_name', locale)
1066-
1067-
def month_name(self, locale=None) -> str:
1068-
"""
1069-
Return the month name of the Timestamp with specified locale.
1070-
1071-
Parameters
1072-
----------
1073-
locale : str, default None (English locale)
1074-
Locale determining the language in which to return the month name.
1075-
1076-
Returns
1077-
-------
1078-
month_name : string
1079-
1080-
.. versionadded:: 0.23.0
1081-
"""
1082-
return self._get_date_name_field('month_name', locale)
1083-
1084-
@property
1085-
def dayofyear(self) -> int:
1086-
"""
1087-
Return the day of the year.
1088-
"""
1089-
return ccalendar.get_day_of_year(self.year, self.month, self.day)
1090-
1091-
@property
1092-
def week(self) -> int:
1093-
"""
1094-
Return the week number of the year.
1095-
"""
1096-
return ccalendar.get_week_of_year(self.year, self.month, self.day)
1097-
1098-
weekofyear = week
1099-
1100-
@property
1101-
def quarter(self) -> int:
1102-
"""
1103-
Return the quarter of the year.
1104-
"""
1105-
return ((self.month - 1) // 3) + 1
1106-
1107-
@property
1108-
def days_in_month(self) -> int:
1109-
"""
1110-
Return the number of days in the month.
1111-
"""
1112-
return ccalendar.get_days_in_month(self.year, self.month)
1113-
1114-
daysinmonth = days_in_month
1115-
11161186
@property
11171187
def freqstr(self):
11181188
"""
11191189
Return the total number of days in the month.
11201190
"""
11211191
return getattr(self.freq, 'freqstr', self.freq)
11221192

1123-
@property
1124-
def is_month_start(self) -> bool:
1125-
"""
1126-
Return True if date is first day of month.
1127-
"""
1128-
if self.freq is None:
1129-
# fast-path for non-business frequencies
1130-
return self.day == 1
1131-
return self._get_start_end_field('is_month_start')
1132-
1133-
@property
1134-
def is_month_end(self) -> bool:
1135-
"""
1136-
Return True if date is last day of month.
1137-
"""
1138-
if self.freq is None:
1139-
# fast-path for non-business frequencies
1140-
return self.day == self.days_in_month
1141-
return self._get_start_end_field('is_month_end')
1142-
1143-
@property
1144-
def is_quarter_start(self) -> bool:
1145-
"""
1146-
Return True if date is first day of the quarter.
1147-
"""
1148-
if self.freq is None:
1149-
# fast-path for non-business frequencies
1150-
return self.day == 1 and self.month % 3 == 1
1151-
return self._get_start_end_field('is_quarter_start')
1152-
1153-
@property
1154-
def is_quarter_end(self) -> bool:
1155-
"""
1156-
Return True if date is last day of the quarter.
1157-
"""
1158-
if self.freq is None:
1159-
# fast-path for non-business frequencies
1160-
return (self.month % 3) == 0 and self.day == self.days_in_month
1161-
return self._get_start_end_field('is_quarter_end')
1162-
1163-
@property
1164-
def is_year_start(self) -> bool:
1165-
"""
1166-
Return True if date is first day of the year.
1167-
"""
1168-
if self.freq is None:
1169-
# fast-path for non-business frequencies
1170-
return self.day == self.month == 1
1171-
return self._get_start_end_field('is_year_start')
1172-
1173-
@property
1174-
def is_year_end(self) -> bool:
1175-
"""
1176-
Return True if date is last day of the year.
1177-
"""
1178-
if self.freq is None:
1179-
# fast-path for non-business frequencies
1180-
return self.month == 12 and self.day == 31
1181-
return self._get_start_end_field('is_year_end')
1182-
1183-
@property
1184-
def is_leap_year(self) -> bool:
1185-
"""
1186-
Return True if year is a leap year.
1187-
"""
1188-
return bool(ccalendar.is_leapyear(self.year))
1189-
11901193
def tz_localize(self, tz, ambiguous='raise', nonexistent='raise'):
11911194
"""
11921195
Convert naive Timestamp to local time zone, or remove
@@ -1456,6 +1459,10 @@ default 'raise'
14561459
return Timestamp(normalized[0]).tz_localize(own_tz)
14571460

14581461

1462+
# Aliases
1463+
Timestamp.weekofyear = Timestamp.week
1464+
Timestamp.daysinmonth = Timestamp.days_in_month
1465+
14591466
# Add the min and max fields at the class level
14601467
cdef int64_t _NS_UPPER_BOUND = np.iinfo(np.int64).max
14611468
# the smallest value we could actually represent is

0 commit comments

Comments
 (0)