diff --git a/python/pylibcudf/pylibcudf/datetime.pxd b/python/pylibcudf/pylibcudf/datetime.pxd
index 72ce680ba7a..335ef435f9b 100644
--- a/python/pylibcudf/pylibcudf/datetime.pxd
+++ b/python/pylibcudf/pylibcudf/datetime.pxd
@@ -1,15 +1,56 @@
 # Copyright (c) 2024, NVIDIA CORPORATION.
 
-from pylibcudf.libcudf.datetime cimport datetime_component
+from pylibcudf.column cimport Column
+from pylibcudf.libcudf.datetime cimport datetime_component, rounding_frequency
+from pylibcudf.scalar cimport Scalar
 
-from .column cimport Column
+ctypedef fused ColumnOrScalar:
+    Column
+    Scalar
 
+cpdef Column extract_millisecond_fraction(
+    Column input
+)
+
+cpdef Column extract_microsecond_fraction(
+    Column input
+)
 
-cpdef Column extract_year(
-    Column col
+cpdef Column extract_nanosecond_fraction(
+    Column input
 )
 
 cpdef Column extract_datetime_component(
-    Column col,
+    Column input,
     datetime_component component
 )
+
+cpdef Column ceil_datetimes(
+    Column input,
+    rounding_frequency freq
+)
+
+cpdef Column floor_datetimes(
+    Column input,
+    rounding_frequency freq
+)
+
+cpdef Column round_datetimes(
+    Column input,
+    rounding_frequency freq
+)
+
+cpdef Column add_calendrical_months(
+    Column timestamps,
+    ColumnOrScalar months,
+)
+
+cpdef Column day_of_year(Column input)
+
+cpdef Column is_leap_year(Column input)
+
+cpdef Column last_day_of_month(Column input)
+
+cpdef Column extract_quarter(Column input)
+
+cpdef Column days_in_month(Column input)
diff --git a/python/pylibcudf/pylibcudf/datetime.pyx b/python/pylibcudf/pylibcudf/datetime.pyx
index ac4335cca56..9e5e709d81d 100644
--- a/python/pylibcudf/pylibcudf/datetime.pyx
+++ b/python/pylibcudf/pylibcudf/datetime.pyx
@@ -3,41 +3,106 @@ from libcpp.memory cimport unique_ptr
 from libcpp.utility cimport move
 from pylibcudf.libcudf.column.column cimport column
 from pylibcudf.libcudf.datetime cimport (
+    add_calendrical_months as cpp_add_calendrical_months,
+    ceil_datetimes as cpp_ceil_datetimes,
     datetime_component,
+    day_of_year as cpp_day_of_year,
+    days_in_month as cpp_days_in_month,
     extract_datetime_component as cpp_extract_datetime_component,
-    extract_year as cpp_extract_year,
+    extract_microsecond_fraction as cpp_extract_microsecond_fraction,
+    extract_millisecond_fraction as cpp_extract_millisecond_fraction,
+    extract_nanosecond_fraction as cpp_extract_nanosecond_fraction,
+    extract_quarter as cpp_extract_quarter,
+    floor_datetimes as cpp_floor_datetimes,
+    is_leap_year as cpp_is_leap_year,
+    last_day_of_month as cpp_last_day_of_month,
+    round_datetimes as cpp_round_datetimes,
+    rounding_frequency,
 )
 
 from pylibcudf.libcudf.datetime import \
     datetime_component as DatetimeComponent  # no-cython-lint
+from pylibcudf.libcudf.datetime import \
+    rounding_frequency as RoundingFrequency  # no-cython-lint
+
+from cython.operator cimport dereference
 
 from .column cimport Column
 
+cpdef Column extract_millisecond_fraction(
+    Column input
+):
+    """
+    Extract the millisecond from a datetime column.
+
+    For details, see :cpp:func:`extract_millisecond_fraction`.
+
+    Parameters
+    ----------
+    input : Column
+        The column to extract the millisecond from.
+
+    Returns
+    -------
+    Column
+        Column with the extracted milliseconds.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_extract_millisecond_fraction(input.view())
+    return Column.from_libcudf(move(result))
+
+cpdef Column extract_microsecond_fraction(
+    Column input
+):
+    """
+    Extract the microsecond fraction from a datetime column.
+
+    For details, see :cpp:func:`extract_microsecond_fraction`.
+
+    Parameters
+    ----------
+    input : Column
+        The column to extract the microsecond fraction from.
+
+    Returns
+    -------
+    Column
+        Column with the extracted microsecond fractions.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_extract_microsecond_fraction(input.view())
+    return Column.from_libcudf(move(result))
 
-cpdef Column extract_year(
-    Column values
+cpdef Column extract_nanosecond_fraction(
+    Column input
 ):
     """
-    Extract the year from a datetime column.
+    Extract the nanosecond fraction from a datetime column.
+
+    For details, see :cpp:func:`extract_nanosecond_fraction`.
 
     Parameters
     ----------
-    values : Column
-        The column to extract the year from.
+    input : Column
+        The column to extract the nanosecond fraction from.
 
     Returns
     -------
     Column
-        Column with the extracted years.
+        Column with the extracted nanosecond fractions.
     """
     cdef unique_ptr[column] result
 
     with nogil:
-        result = cpp_extract_year(values.view())
+        result = cpp_extract_nanosecond_fraction(input.view())
     return Column.from_libcudf(move(result))
 
 cpdef Column extract_datetime_component(
-    Column values,
+    Column input,
     datetime_component component
 ):
     """
@@ -47,7 +112,7 @@ cpdef Column extract_datetime_component(
 
     Parameters
     ----------
-    values : Column
+    input : Column
         The column to extract the component from.
     component : DatetimeComponent
         The datetime component to extract.
@@ -60,5 +125,237 @@ cpdef Column extract_datetime_component(
     cdef unique_ptr[column] result
 
     with nogil:
-        result = cpp_extract_datetime_component(values.view(), component)
+        result = cpp_extract_datetime_component(input.view(), component)
+    return Column.from_libcudf(move(result))
+
+cpdef Column ceil_datetimes(
+    Column input,
+    rounding_frequency freq
+):
+    """
+    Round datetimes up to the nearest multiple of the given frequency.
+
+    For details, see :cpp:func:`ceil_datetimes`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+    freq : rounding_frequency
+        The frequency to round up to.
+
+    Returns
+    -------
+    Column
+        Column of the same datetime resolution as the input column.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_ceil_datetimes(input.view(), freq)
+    return Column.from_libcudf(move(result))
+
+cpdef Column floor_datetimes(
+    Column input,
+    rounding_frequency freq
+):
+    """
+    Round datetimes down to the nearest multiple of the given frequency.
+
+    For details, see :cpp:func:`floor_datetimes`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+    freq : rounding_frequency
+        The frequency to round down to.
+
+    Returns
+    -------
+    Column
+        Column of the same datetime resolution as the input column.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_floor_datetimes(input.view(), freq)
+    return Column.from_libcudf(move(result))
+
+cpdef Column round_datetimes(
+    Column input,
+    rounding_frequency freq
+):
+    """
+    Round datetimes to the nearest multiple of the given frequency.
+
+    For details, see :cpp:func:`round_datetimes`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+    freq : rounding_frequency
+        The frequency to round to.
+
+    Returns
+    -------
+    Column
+        Column of the same datetime resolution as the input column.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_round_datetimes(input.view(), freq)
+    return Column.from_libcudf(move(result))
+
+cpdef Column add_calendrical_months(
+    Column input,
+    ColumnOrScalar months,
+):
+    """
+    Adds or subtracts a number of months from the datetime
+    type and returns a timestamp column that is of the same
+    type as the input timestamps column.
+
+    For details, see :cpp:func:`add_calendrical_months`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input timestamp values.
+    months : ColumnOrScalar
+        The number of months to add.
+
+    Returns
+    -------
+    Column
+        Column of computed timestamps.
+    """
+    if not isinstance(months, (Column, Scalar)):
+        raise TypeError("Must pass a Column or Scalar")
+
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_add_calendrical_months(
+            input.view(),
+            months.view() if ColumnOrScalar is Column else
+            dereference(months.get())
+        )
+    return Column.from_libcudf(move(result))
+
+cpdef Column day_of_year(Column input):
+    """
+    Computes the day number since the start of
+    the year from the datetime. The value is between
+    [1, {365-366}].
+
+    For details, see :cpp:func:`day_of_year`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+
+    Returns
+    -------
+    Column
+        Column of day numbers.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_day_of_year(input.view())
+    return Column.from_libcudf(move(result))
+
+cpdef Column is_leap_year(Column input):
+    """
+    Check if the year of the given date is a leap year.
+
+    For details, see :cpp:func:`is_leap_year`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+
+    Returns
+    -------
+    Column
+        Column of bools indicating whether the given year
+        is a leap year.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_is_leap_year(input.view())
+    return Column.from_libcudf(move(result))
+
+cpdef Column last_day_of_month(Column input):
+    """
+    Computes the last day of the month.
+
+    For details, see :cpp:func:`last_day_of_month`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+
+    Returns
+    -------
+    Column
+        Column of ``TIMESTAMP_DAYS`` representing the last day
+        of the month.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_last_day_of_month(input.view())
+    return Column.from_libcudf(move(result))
+
+cpdef Column extract_quarter(Column input):
+    """
+    Returns the quarter (ie. a value from {1, 2, 3, 4})
+    that the date is in.
+
+    For details, see :cpp:func:`extract_quarter`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+
+    Returns
+    -------
+    Column
+        Column indicating which quarter the date is in.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_extract_quarter(input.view())
+    return Column.from_libcudf(move(result))
+
+cpdef Column days_in_month(Column input):
+    """
+    Extract the number of days in the month.
+
+    For details, see :cpp:func:`days_in_month`.
+
+    Parameters
+    ----------
+    input : Column
+        The column of input datetime values.
+
+    Returns
+    -------
+    Column
+        Column of the number of days in the given month.
+    """
+    cdef unique_ptr[column] result
+
+    with nogil:
+        result = cpp_days_in_month(input.view())
     return Column.from_libcudf(move(result))
diff --git a/python/pylibcudf/pylibcudf/libcudf/datetime.pxd b/python/pylibcudf/pylibcudf/libcudf/datetime.pxd
index 73cdfb96af5..8bbc120cff8 100644
--- a/python/pylibcudf/pylibcudf/libcudf/datetime.pxd
+++ b/python/pylibcudf/pylibcudf/libcudf/datetime.pxd
@@ -1,6 +1,6 @@
 # Copyright (c) 2020-2024, NVIDIA CORPORATION.
 
-from libc.stdint cimport uint8_t
+from libc.stdint cimport int32_t, uint8_t
 from libcpp.memory cimport unique_ptr
 from pylibcudf.libcudf.column.column cimport column
 from pylibcudf.libcudf.column.column_view cimport column_view
@@ -41,14 +41,14 @@ cdef extern from "cudf/datetime.hpp" namespace "cudf::datetime" nogil:
         datetime_component component
     ) except +
 
-    ctypedef enum rounding_frequency "cudf::datetime::rounding_frequency":
-        DAY "cudf::datetime::rounding_frequency::DAY"
-        HOUR "cudf::datetime::rounding_frequency::HOUR"
-        MINUTE "cudf::datetime::rounding_frequency::MINUTE"
-        SECOND "cudf::datetime::rounding_frequency::SECOND"
-        MILLISECOND "cudf::datetime::rounding_frequency::MILLISECOND"
-        MICROSECOND "cudf::datetime::rounding_frequency::MICROSECOND"
-        NANOSECOND "cudf::datetime::rounding_frequency::NANOSECOND"
+    cpdef enum class rounding_frequency(int32_t):
+        DAY
+        HOUR
+        MINUTE
+        SECOND
+        MILLISECOND
+        MICROSECOND
+        NANOSECOND
 
     cdef unique_ptr[column] ceil_datetimes(
         const column_view& column, rounding_frequency freq
@@ -64,6 +64,10 @@ cdef extern from "cudf/datetime.hpp" namespace "cudf::datetime" nogil:
         const column_view& timestamps,
         const column_view& months
     ) except +
+    cdef unique_ptr[column] add_calendrical_months(
+        const column_view& timestamps,
+        const scalar& months
+    ) except +
     cdef unique_ptr[column] day_of_year(const column_view& column) except +
     cdef unique_ptr[column] is_leap_year(const column_view& column) except +
     cdef unique_ptr[column] last_day_of_month(
diff --git a/python/pylibcudf/pylibcudf/tests/test_datetime.py b/python/pylibcudf/pylibcudf/tests/test_datetime.py
index a80ab8d9f65..f5f24ef28e2 100644
--- a/python/pylibcudf/pylibcudf/tests/test_datetime.py
+++ b/python/pylibcudf/pylibcudf/tests/test_datetime.py
@@ -1,5 +1,6 @@
 # Copyright (c) 2024, NVIDIA CORPORATION.
 
+import calendar
 import datetime
 
 import pyarrow as pa
@@ -46,6 +47,21 @@ def component(request):
     return request.param
 
 
+@pytest.fixture(
+    params=[
+        ("day", plc.datetime.RoundingFrequency.DAY),
+        ("hour", plc.datetime.RoundingFrequency.HOUR),
+        ("minute", plc.datetime.RoundingFrequency.MINUTE),
+        ("second", plc.datetime.RoundingFrequency.SECOND),
+        ("millisecond", plc.datetime.RoundingFrequency.MILLISECOND),
+        ("microsecond", plc.datetime.RoundingFrequency.MICROSECOND),
+        ("nanosecond", plc.datetime.RoundingFrequency.NANOSECOND),
+    ]
+)
+def rounding_frequency(request):
+    return request.param
+
+
 def test_extract_datetime_component(datetime_column, component):
     attr, component = component
     kwargs = {}
@@ -59,3 +75,139 @@ def test_extract_datetime_component(datetime_column, component):
     ).cast(pa.int16())
 
     assert_column_eq(expect, got)
+
+
+@pytest.mark.parametrize(
+    "datetime_func",
+    [
+        "extract_millisecond_fraction",
+        "extract_microsecond_fraction",
+        "extract_nanosecond_fraction",
+    ],
+)
+def test_datetime_extracting_functions(datetime_column, datetime_func):
+    pa_col = plc.interop.to_arrow(datetime_column)
+    got = getattr(plc.datetime, datetime_func)(datetime_column)
+    kwargs = {}
+    attr = datetime_func.split("_")[1]
+    if attr == "weekday":
+        kwargs = {"count_from_zero": False}
+        attr = "day_of_week"
+    expect = getattr(pc, attr)(pa_col, **kwargs).cast(pa.int16())
+    assert_column_eq(expect, got)
+
+
+@pytest.mark.parametrize(
+    "op",
+    [
+        ("ceil_temporal", "ceil_datetimes"),
+        ("floor_temporal", "floor_datetimes"),
+        ("round_temporal", "round_datetimes"),
+    ],
+)
+def test_rounding_operations(datetime_column, op, rounding_frequency):
+    got = getattr(plc.datetime, op[1])(datetime_column, rounding_frequency[1])
+    pa_col = plc.interop.to_arrow(datetime_column)
+    pa_got = plc.interop.to_arrow(got)
+    expect = getattr(pc, op[0])(
+        pa_col,
+        unit=rounding_frequency[0],
+    ).cast(pa_got.type)
+    assert_column_eq(expect, got)
+
+
+@pytest.mark.parametrize(
+    "months",
+    [
+        pa.scalar(-3, pa.int32()),
+        pa.scalar(1, pa.int16()),
+        pa.array([1, -3, 2, 4, -1, 5], pa.int32()),
+    ],
+)
+def test_calendrical_months(datetime_column, months):
+    def add_calendrical_months(timestamps, months):
+        result = []
+        if isinstance(months, pa.Array):
+            months_list = months.to_pylist()
+        else:
+            months_list = [months.as_py()] * len(timestamps)
+        for i, dt in enumerate(timestamps):
+            if dt.as_py() is not None:
+                year, month = dt.as_py().year, dt.as_py().month
+                new_month = month + months_list[i]
+                new_year = year + (new_month - 1) // 12
+                result.append(
+                    dt.as_py().replace(
+                        year=new_year, month=(new_month - 1) % 12 + 1
+                    )
+                )
+            else:
+                result.append(None)
+        return pa.array(result)
+
+    pa_col = plc.interop.to_arrow(datetime_column)
+    got = plc.datetime.add_calendrical_months(
+        datetime_column, plc.interop.from_arrow(months)
+    )
+    pa_got = plc.interop.to_arrow(got)
+    expect = add_calendrical_months(pa_col, months).cast(pa_got.type)
+    assert_column_eq(expect, got)
+
+
+def test_day_of_year(datetime_column):
+    got = plc.datetime.day_of_year(datetime_column)
+    pa_got = plc.interop.to_arrow(got)
+    pa_col = plc.interop.to_arrow(datetime_column)
+    expect = pa.array(
+        [
+            d.as_py().timetuple().tm_yday if d.as_py() is not None else None
+            for d in pa_col
+        ],
+        type=pa_got.type,
+    )
+    assert_column_eq(expect, got)
+
+
+def test_is_leap_year(datetime_column):
+    got = plc.datetime.is_leap_year(datetime_column)
+    pa_col = plc.interop.to_arrow(datetime_column)
+    expect = pc.is_leap_year(pa_col)
+    assert_column_eq(expect, got)
+
+
+def test_last_day_of_month(datetime_column):
+    def last_day_of_month(dates):
+        return [
+            d.replace(day=calendar.monthrange(d.year, d.month)[1])
+            if d is not None
+            else d
+            for d in dates.to_pylist()
+        ]
+
+    got = plc.datetime.last_day_of_month(datetime_column)
+    pa_got = plc.interop.to_arrow(got)
+    pa_col = plc.interop.to_arrow(datetime_column)
+    expect = pa.array(last_day_of_month(pa_col), type=pa_got.type)
+    assert_column_eq(expect, got)
+
+
+def test_extract_quarter(datetime_column):
+    got = plc.datetime.extract_quarter(datetime_column)
+    pa_col = plc.interop.to_arrow(datetime_column)
+    pa_got = plc.interop.to_arrow(got)
+    expect = pc.quarter(pa_col).cast(pa_got.type)
+    assert_column_eq(expect, got)
+
+
+def test_days_in_month(datetime_column):
+    def days_in_month(dates):
+        return [
+            calendar.monthrange(d.year, d.month)[1] if d is not None else None
+            for d in dates.to_pylist()
+        ]
+
+    got = plc.datetime.days_in_month(datetime_column)
+    pa_col = plc.interop.to_arrow(datetime_column)
+    pa_got = plc.interop.to_arrow(got)
+    expect = pa.array(days_in_month(pa_col), type=pa_got.type)
+    assert_column_eq(expect, got)