diff --git a/doc/source/user_guide/timeseries.rst b/doc/source/user_guide/timeseries.rst
index 10260cb011d90..43948bbdcb678 100644
--- a/doc/source/user_guide/timeseries.rst
+++ b/doc/source/user_guide/timeseries.rst
@@ -1065,9 +1065,9 @@ Holiday calendars can be used to provide the list of holidays.  See the
 
 .. ipython:: python
 
-    from pandas.tseries.holiday import USFederalHolidayCalendar
+    calendar = np.busdaycalendar(holidays=['2014-01-01', '2014-01-20'])
 
-    bday_us = pd.offsets.CustomBusinessDay(calendar=USFederalHolidayCalendar())
+    bday_us = pd.offsets.CustomBusinessDay(calendar=calendar)
 
     # Friday before MLK Day
     dt = datetime.datetime(2014, 1, 17)
@@ -1080,7 +1080,8 @@ in the usual way.
 
 .. ipython:: python
 
-    bmth_us = pd.offsets.CustomBusinessMonthBegin(calendar=USFederalHolidayCalendar())
+    bdd = np.busdaycalendar(holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+    bmth_us = pd.offsets.CustomBusinessMonthBegin(calendar=bdd)
 
     # Skip new years
     dt = datetime.datetime(2013, 12, 17)
@@ -1210,9 +1211,9 @@ as ``BusinessHour`` except that it skips specified custom holidays.
 
 .. ipython:: python
 
-    from pandas.tseries.holiday import USFederalHolidayCalendar
+   calendar = np.busdaycalendar(holidays=['2014-01-01', '2014-01-20'])
 
-    bhour_us = pd.offsets.CustomBusinessHour(calendar=USFederalHolidayCalendar())
+    bhour_us = pd.offsets.CustomBusinessHour(calendar=calendar)
     # Friday before MLK Day
     dt = datetime.datetime(2014, 1, 17, 15)
 
diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst
index 29be9a7341f00..797e8e95f7ee4 100644
--- a/doc/source/whatsnew/v3.0.0.rst
+++ b/doc/source/whatsnew/v3.0.0.rst
@@ -476,6 +476,7 @@ Other Removals
 - Disallow indexing an :class:`Index` with a boolean indexer of length zero, it now raises ``ValueError`` (:issue:`55820`)
 - Disallow non-standard (``np.ndarray``, :class:`Index`, :class:`ExtensionArray`, or :class:`Series`) to :func:`isin`, :func:`unique`, :func:`factorize` (:issue:`52986`)
 - Disallow passing a pandas type to :meth:`Index.view` (:issue:`55709`)
+- Disallow passing objects other than ``np.busdaycalendar`` to ``calendar`` parameter in :class:`CustomBusinessDay` (:issue:`60647`)
 - Disallow units other than "s", "ms", "us", "ns" for datetime64 and timedelta64 dtypes in :func:`array` (:issue:`53817`)
 - Removed "freq" keyword from :class:`PeriodArray` constructor, use "dtype" instead (:issue:`52462`)
 - Removed 'fastpath' keyword in :class:`Categorical` constructor (:issue:`20110`)
diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index a16964435ef50..4f87a76e5e487 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -4666,6 +4666,11 @@ cdef class CustomBusinessDay(BusinessDay):
         offset=timedelta(0),
     ):
         BusinessDay.__init__(self, n, normalize, offset)
+        if calendar is not None and not isinstance(calendar, np.busdaycalendar):
+            raise TypeError(
+                f"Only np.busdaycalendar is supported for calendar, "
+                f"got {type(calendar).__name__} instead"
+            )
         self._init_custom(weekmask, holidays, calendar)
 
     cpdef __setstate__(self, state):
@@ -4822,6 +4827,11 @@ cdef class CustomBusinessHour(BusinessHour):
         offset=timedelta(0),
     ):
         BusinessHour.__init__(self, n, normalize, start=start, end=end, offset=offset)
+        if calendar is not None and not isinstance(calendar, np.busdaycalendar):
+            raise TypeError(
+                f"Only np.busdaycalendar is supported for calendar, "
+                f"got {type(calendar).__name__} instead"
+            )
         self._init_custom(weekmask, holidays, calendar)
 
 
@@ -4840,6 +4850,11 @@ cdef class _CustomBusinessMonth(BusinessMixin):
         offset=timedelta(0),
     ):
         BusinessMixin.__init__(self, n, normalize, offset)
+        if calendar is not None and not isinstance(calendar, np.busdaycalendar):
+            raise TypeError(
+                f"Only np.busdaycalendar is supported for calendar, "
+                f"got {type(calendar).__name__} instead"
+            )
         self._init_custom(weekmask, holidays, calendar)
 
     @cache_readonly
@@ -5108,8 +5123,8 @@ def _warn_about_deprecated_aliases(name: str, is_period: bool) -> str:
         warnings.warn(
             f"\'{name}\' is deprecated and will be removed "
             f"in a future version, please use "
-            f"\'{c_PERIOD_AND_OFFSET_DEPR_FREQSTR.get(name)}\'"
-            f" instead.",
+            f"\'{c_PERIOD_AND_OFFSET_DEPR_FREQSTR.get(name)}\' "
+            f"instead.",
             FutureWarning,
             stacklevel=find_stack_level(),
             )
@@ -5122,8 +5137,8 @@ def _warn_about_deprecated_aliases(name: str, is_period: bool) -> str:
             warnings.warn(
                 f"\'{name}\' is deprecated and will be removed "
                 f"in a future version, please use "
-                f"\'{_name}\'"
-                f" instead.",
+                f"\'{_name}\' "
+                f"instead.",
                 FutureWarning,
                 stacklevel=find_stack_level(),
                 )
diff --git a/pandas/tests/tseries/holiday/test_calendar.py b/pandas/tests/tseries/holiday/test_calendar.py
index 90e2e117852a2..864bbe7ef3feb 100644
--- a/pandas/tests/tseries/holiday/test_calendar.py
+++ b/pandas/tests/tseries/holiday/test_calendar.py
@@ -1,5 +1,6 @@
 from datetime import datetime
 
+import numpy as np
 import pytest
 
 from pandas import (
@@ -14,7 +15,6 @@
     Holiday,
     Timestamp,
     USFederalHolidayCalendar,
-    USLaborDay,
     USThanksgivingDay,
     get_calendar,
 )
@@ -97,10 +97,7 @@ def test_calendar_2031():
     # Labor Day 2031 is on September 1. Saturday before is August 30.
     # Next working day after August 30 ought to be Tuesday, September 2.
 
-    class testCalendar(AbstractHolidayCalendar):
-        rules = [USLaborDay]
-
-    cal = testCalendar()
+    cal = np.busdaycalendar(holidays=["2031-09-01"])
     workDay = offsets.CustomBusinessDay(calendar=cal)
     Sat_before_Labor_Day_2031 = to_datetime("2031-08-30")
     next_working_day = Sat_before_Labor_Day_2031 + 0 * workDay
diff --git a/pandas/tests/tseries/offsets/test_custom_business_day.py b/pandas/tests/tseries/offsets/test_custom_business_day.py
index d2f309dd3f33c..4b16d6ba3d87a 100644
--- a/pandas/tests/tseries/offsets/test_custom_business_day.py
+++ b/pandas/tests/tseries/offsets/test_custom_business_day.py
@@ -10,7 +10,11 @@
 import numpy as np
 import pytest
 
-from pandas._libs.tslibs.offsets import CDay
+from pandas._libs.tslibs.offsets import (
+    BDay,
+    CDay,
+    CustomBusinessDay,
+)
 
 from pandas import (
     _testing as tm,
@@ -18,8 +22,6 @@
 )
 from pandas.tests.tseries.offsets.common import assert_offset_equal
 
-from pandas.tseries.holiday import USFederalHolidayCalendar
-
 
 @pytest.fixture
 def offset():
@@ -78,7 +80,7 @@ def test_weekmask_and_holidays(self):
 
     @pytest.mark.filterwarnings("ignore:Non:pandas.errors.PerformanceWarning")
     def test_calendar(self):
-        calendar = USFederalHolidayCalendar()
+        calendar = np.busdaycalendar(holidays=["2014-01-01", "2014-01-20"])
         dt = datetime(2014, 1, 17)
         assert_offset_equal(CDay(calendar=calendar), dt, datetime(2014, 1, 21))
 
@@ -97,3 +99,9 @@ def test_pickle_compat_0_14_1(self, datapath):
         cday0_14_1 = read_pickle(pth)
         cday = CDay(holidays=hdays)
         assert cday == cday0_14_1
+
+    def test_type_error_calendar(self):
+        bd = BDay(1)
+        msg = "Only np.busdaycalendar is supported for calendar"
+        with pytest.raises(TypeError, match=msg):
+            CustomBusinessDay(calendar=bd)
diff --git a/pandas/tests/tseries/offsets/test_custom_business_hour.py b/pandas/tests/tseries/offsets/test_custom_business_hour.py
index 360ed70fa5b9e..236abe63dc11a 100644
--- a/pandas/tests/tseries/offsets/test_custom_business_hour.py
+++ b/pandas/tests/tseries/offsets/test_custom_business_hour.py
@@ -21,8 +21,6 @@
 
 from pandas.tests.tseries.offsets.common import assert_offset_equal
 
-from pandas.tseries.holiday import USFederalHolidayCalendar
-
 holidays = ["2014-06-27", datetime(2014, 6, 30), np.datetime64("2014-07-02")]
 
 
@@ -299,7 +297,8 @@ def test_apply_nanoseconds(self, nano_case):
 
     def test_us_federal_holiday_with_datetime(self):
         # GH 16867
-        bhour_us = CustomBusinessHour(calendar=USFederalHolidayCalendar())
+        calendar = np.busdaycalendar(holidays=["2014-01-01", "2014-01-20"])
+        bhour_us = CustomBusinessHour(calendar=calendar)
         t0 = datetime(2014, 1, 17, 15)
         result = t0 + bhour_us * 8
         expected = Timestamp("2014-01-21 15:00:00")