Repository: dask/dask

Issue:
dask.dataframe.pivot_table seems to destroy datetime type information on the new index 
I ran into an issue when using pivot_table on a dask.dataframe recently: when selecting a column with type `datetime64[ns]` as the new index, the dtype of the index is `object` afterwards. I have generated some mock data below resembling the original data which is coming from machine sensors:

```
import numpy as np
import pandas as pd
import dask.dataframe as dd


df = pd.DataFrame({'dateTime': np.repeat(pd.date_range(start='2019-08-01',
                                         periods=2000,
                                         freq='s'), 5),
                   'plantCode': np.random.choice(['P1', 'P2', 'P3'], size=10000),
                   'value': np.random.uniform(0, 100, 10000),
                   'variableName': np.random.choice(['xyz', 'abc', 'xoxo', 'lol', 'wtf'], size=10000)})

ddf = dd.from_pandas(df, npartitions=10).categorize()
ddf.info()
```

Output (dtypes as expected):
```
<class 'dask.dataframe.core.DataFrame'>
Columns: 4 entries, dateTime to variableName
dtypes: category(1), category(1), datetime64[ns](1), float64(1)
```

Now pivot the table:
```
ddf_pivot = ddf.pivot_table(index='dateTime', columns='variableName', values='value')
ddf_pivot.index
```

Output (index type is `object`):
```
Dask Index Structure:
npartitions=1
    object
       ...
Name: dateTime, dtype: object
Dask Name: truediv, 48 tasks
```


Mapping the index manually after the pivot resulted in all entries being `NaT`:
```
ddf_pivot.index = ddf_pivot.index.map_partitions(pd.to_datetime,
                                                 meta='M8',
                                                 infer_datetime_format=True, 
                                                 errors='coerce')
ddf_pivot.index
```
Output:
```
Dask Index Structure:
npartitions=1
NaT    datetime64[ns]
NaT               ...
dtype: datetime64[ns]
Dask Name: assign_index, 51 tasks
```


Discussion:
Thanks for the report! The following seems to fix it, at least for this case.

```diff
diff --git a/dask/dataframe/reshape.py b/dask/dataframe/reshape.py
index ca166710e..f3df2a213 100644
--- a/dask/dataframe/reshape.py
+++ b/dask/dataframe/reshape.py
@@ -238,8 +238,8 @@ def pivot_table(df, index=None, columns=None, values=None, aggfunc="mean"):
     # _emulate can't work for empty data
     # the result must have CategoricalIndex columns
     new_columns = pd.CategoricalIndex(df[columns].cat.categories, name=columns)
-    meta = pd.DataFrame(columns=new_columns, dtype=np.float64)
-    meta.index.name = index
+    meta = pd.DataFrame(columns=new_columns, dtype=np.float64,
+                        index=pd.Index(df._meta[index]))
 
     kwargs = {"index": index, "columns": columns, "values": values}
```

With that, I get

```python
In [2]: ddf_pivot = ddf.pivot_table(index='dateTime', columns='variableName', values='value')
   ...: ddf_pivot.index
   ...:
Out[2]:
Dask Index Structure:
npartitions=1
    datetime64[ns]
               ...
Name: dateTime, dtype: datetime64[ns]
Dask Name: truediv, 48 tasks
```

Would you be interested in submitting a PR with that and tests? Ideally, we would also have tests that cover different index subclass (period, datetimetz, categorical, interval), but at least covering datetime would be a start.
Thank you for the very quick reply - not something we're used to with our enterprise software vendors :)
I will look into submitting a PR later this week.

Resolving patch:
diff --git a/dask/dataframe/reshape.py b/dask/dataframe/reshape.py
--- a/dask/dataframe/reshape.py
+++ b/dask/dataframe/reshape.py
@@ -238,8 +238,9 @@ def pivot_table(df, index=None, columns=None, values=None, aggfunc="mean"):
     # _emulate can't work for empty data
     # the result must have CategoricalIndex columns
     new_columns = pd.CategoricalIndex(df[columns].cat.categories, name=columns)
-    meta = pd.DataFrame(columns=new_columns, dtype=np.float64)
-    meta.index.name = index
+    meta = pd.DataFrame(
+        columns=new_columns, dtype=np.float64, index=pd.Index(df._meta[index])
+    )
 
     kwargs = {"index": index, "columns": columns, "values": values}
 


Test patch:
diff --git a/dask/dataframe/tests/test_reshape.py b/dask/dataframe/tests/test_reshape.py
--- a/dask/dataframe/tests/test_reshape.py
+++ b/dask/dataframe/tests/test_reshape.py
@@ -246,6 +246,20 @@ def test_pivot_table_dtype():
     assert_eq(res, exp)
 
 
+def test_pivot_table_index_dtype():
+    df = pd.DataFrame(
+        {
+            "A": pd.date_range(start="2019-08-01", periods=3, freq="1D"),
+            "B": pd.Categorical(list("abc")),
+            "C": [1, 2, 3],
+        }
+    )
+    ddf = dd.from_pandas(df, 2)
+    res = dd.pivot_table(ddf, index="A", columns="B", values="C", aggfunc="count")
+
+    assert res.index.dtype == np.dtype("datetime64[ns]")
+
+
 def test_pivot_table_errors():
     df = pd.DataFrame(
         {