diff --git a/Project.toml b/Project.toml
index b7770094..ecf1f953 100644
--- a/Project.toml
+++ b/Project.toml
@@ -26,8 +26,9 @@ julia = "1.6.1"
 
 [extras]
 Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
+DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
 Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
 TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
 
 [targets]
-test = ["Aqua", "Test", "TestItemRunner"]
+test = ["Aqua", "Test", "TestItemRunner", "DataFrames"]
diff --git a/src/Py.jl b/src/Py.jl
index 13fbdb02..b815ca9a 100644
--- a/src/Py.jl
+++ b/src/Py.jl
@@ -148,6 +148,7 @@ Py(x::AbstractRange{<:Union{Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UI
 Py(x::Date) = pydate(x)
 Py(x::Time) = pytime(x)
 Py(x::DateTime) = pydatetime(x)
+Py(x::Union{Period, Dates.CompoundPeriod}) = pytimedelta64(x)
 Py(x) = ispy(x) ? throw(MethodError(Py, (x,))) : pyjl(x)
 
 Base.string(x::Py) = pyisnull(x) ? "<py NULL>" : pystr(String, x)
diff --git a/src/concrete/datetime.jl b/src/concrete/datetime.jl
index 1e0c41a8..76fbe50a 100644
--- a/src/concrete/datetime.jl
+++ b/src/concrete/datetime.jl
@@ -33,6 +33,40 @@ end
 pydatetime(x::Date) = pydatetime(year(x), month(x), day(x))
 export pydatetime
 
+function pytimedelta64(_year=0, _month=0, _day=0, _hour=0, _minute=0, _second=0, _millisecond=0, _microsecond=0, _nanosecond=0; year=_year, month=_month, day=_day, hour=_hour, minute=_minute, second=_second, microsecond=_microsecond, millisecond=_millisecond, nanosecond=_nanosecond)
+    pytimedelta64(sum((
+        Year(year), Month(month), Day(day), Hour(hour),
+        Minute(minute), Second(second), Millisecond(millisecond), Microsecond(microsecond), Nanosecond(nanosecond))
+    ))
+end
+
+function pytimedelta64(@nospecialize(x::T)) where T <: Period
+    unit = if T==Year
+        "Y"
+    elseif T==Month
+        "M"
+    elseif T==Day
+        "D"
+    elseif T==Hour
+        "h"
+    elseif T==Minute
+        "m"
+    elseif T==Second
+        "s"
+    elseif T==Millisecond
+        "ms"
+    elseif T==Microsecond
+        "us"
+    elseif T==Nanosecond
+        "ns"
+    else
+        ""
+    end
+    pyimport("numpy").timedelta64(x.value, unit)
+end
+pytimedelta64(x::Dates.CompoundPeriod) = isempty(x.periods) ? pytimedelta64(Second(0)) : sum(pytimedelta64.(x.periods))
+export pytimedelta64
+
 function pytime_isaware(x)
     tzinfo = pygetattr(x, "tzinfo")
     if pyisnone(tzinfo)
@@ -93,3 +127,28 @@ function pyconvert_rule_datetime(::Type{DateTime}, x::Py)
     iszero(mod(microseconds, 1000)) || return pyconvert_unconverted()
     return pyconvert_return(_base_datetime + Millisecond(div(microseconds, 1000) + 1000 * (seconds + 60 * 60 * 24 * days)))
 end
+
+function pyconvert_rule_datetime64(::Type{DateTime}, x::Py)
+    pyconvert(DateTime, pyimport("pandas").to_datetime(x))
+end
+
+function pyconvert_rule_timedelta(::Type{<:Dates.CompoundPeriod}, x::Py)
+    days = pyconvert(Int, x.days)
+    seconds = pyconvert(Int, x.seconds)
+    microseconds = pyconvert(Int, x.microseconds)
+    nanoseconds = pyhasattr(x, "nanoseconds") ? pyconvert(Int, x.nanoseconds) : 0
+    timedelta = Day(days) + Second(seconds) + Microsecond(microseconds) + Nanosecond(nanoseconds)
+    return pyconvert_return(timedelta)
+end
+
+function pyconvert_rule_timedelta(::Type{T}, x::Py) where T<:Period
+    pyconvert_return(convert(T, pyconvert_rule_timedelta(Dates.CompoundPeriod, x)))
+end
+
+function pyconvert_rule_timedelta64(::Type{Dates.CompoundPeriod}, x::Py)
+    pyconvert_rule_timedelta(Dates.CompoundPeriod, pyimport("pandas").to_timedelta(x))
+end
+
+function pyconvert_rule_timedelta64(::Type{T}, x::Py) where T<:Period
+    pyconvert_return(convert(T, pyconvert_rule_timedelta64(Dates.CompoundPeriod, x)))
+end
\ No newline at end of file
diff --git a/src/convert.jl b/src/convert.jl
index 498293a5..402b01fd 100644
--- a/src/convert.jl
+++ b/src/convert.jl
@@ -390,12 +390,21 @@ function init_pyconvert()
 
     priority = PYCONVERT_PRIORITY_WRAP
     pyconvert_add_rule("juliacall:ValueBase", Any, pyconvert_rule_jlvalue, priority)
-
+    
     priority = PYCONVERT_PRIORITY_ARRAY
     pyconvert_add_rule("<arraystruct>", PyArray, pyconvert_rule_array_nocopy, priority)
     pyconvert_add_rule("<arrayinterface>", PyArray, pyconvert_rule_array_nocopy, priority)
     pyconvert_add_rule("<array>", PyArray, pyconvert_rule_array_nocopy, priority)
     pyconvert_add_rule("<buffer>", PyArray, pyconvert_rule_array_nocopy, priority)
+    pyconvert_add_rule("numpy:datetime64", DateTime, pyconvert_rule_datetime64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Dates.CompoundPeriod, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Year, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Month, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Day, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Second, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Millisecond, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Microsecond, pyconvert_rule_timedelta64, priority)
+    pyconvert_add_rule("numpy:timedelta64", Nanosecond, pyconvert_rule_timedelta64, priority)
 
     priority = PYCONVERT_PRIORITY_CANONICAL
     pyconvert_add_rule("builtins:NoneType", Nothing, pyconvert_rule_none, priority)
@@ -420,6 +429,7 @@ function init_pyconvert()
     pyconvert_add_rule("datetime:datetime", DateTime, pyconvert_rule_datetime, priority)
     pyconvert_add_rule("datetime:date", Date, pyconvert_rule_date, priority)
     pyconvert_add_rule("datetime:time", Time, pyconvert_rule_time, priority)
+    pyconvert_add_rule("datetime:timedelta", Dates.CompoundPeriod, pyconvert_rule_timedelta, priority)
     pyconvert_add_rule("builtins:BaseException", PyException, pyconvert_rule_exception, priority)
 
     priority = PYCONVERT_PRIORITY_NORMAL
diff --git a/src/pywrap/PyArray.jl b/src/pywrap/PyArray.jl
index af7933cf..32ca236a 100644
--- a/src/pywrap/PyArray.jl
+++ b/src/pywrap/PyArray.jl
@@ -435,7 +435,7 @@ function pyarray_get_R(src::PyArraySource_ArrayStruct)
     elseif kind == 109  # m = timedelta
         error("timedelta not supported")
     elseif kind == 77  # M = datetime
-        error("datetime not supported")
+        error("datetime64 not supported")
     elseif kind == 79  # O = object
         if size == sizeof(C.PyPtr)
             return UnsafePyObject
diff --git a/test/pywrap.jl b/test/pywrap.jl
index 13b4d3a1..4c53b1dc 100644
--- a/test/pywrap.jl
+++ b/test/pywrap.jl
@@ -339,6 +339,18 @@ end
 end
 
 @testitem "PyPandasDataFrame" begin
+    using Dates
+    using DataFrames
+    using CondaPkg
+    CondaPkg.add("pandas")
+    jdf = DataFrame(x = [now() + Second(rand(1:1000)) for _ in 1:100], y = [Second(n) for n in 1:100])
+    pdf = pytable(jdf)
+    @test PyTable(pdf) isa PyPandasDataFrame
+    @test PythonCall.pyconvert_typename(pdf.x[0]) == "pandas._libs.tslibs.timestamps:<name>"
+    @test PythonCall.pyconvert_typename(pdf.y[0]) == "pandas._libs.tslibs.timedeltas:<name>"
+    jdf2 = DataFrame(PyTable(pdf))
+    @test all((jdf .== jdf2).x)
+    @test all((jdf .== jdf2).y)
 end
 
 @testitem "PySet" begin