BUG: Timedelta not formatted correctly in to_json
State: closed

- [x] closes #28256
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Labels:
name: IO JSON
description: read_json, to_json, json_normalize

Comments:
Hello @cbertinato! Thanks for updating this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:









There are currently no PEP 8 issues detected in this Pull Request. Cheers! :beers: 

##### Comment last updated at 2019-10-05 16:30:59 UTC
There was an existing DataFrame that mixed timedeltas, datetimes, and ints, so just to be safe I added another with only timedeltas. I also added a benchmark with `date_format="iso"`.  Just about all DataFrames containing timedeltas showed significant change:
```
       before           after         ratio
     [4fb853f6]       [aa9749a2]
     <28256-iso-date-json~2>       <28256-iso-date-json>
+        71.4±2ms       3.55±0.07s    49.76  io.json.ToJSON.time_to_json_iso('records', 'df_td')
+        68.8±1ms       3.40±0.06s    49.40  io.json.ToJSON.time_to_json_iso('values', 'df_td')
+        93.4±5ms       3.53±0.06s    37.81  io.json.ToJSON.time_to_json_iso('split', 'df_td')
+         179±7ms       3.79±0.03s    21.14  io.json.ToJSON.time_to_json_iso('split', 'df_td_int_ts')
+        183±20ms       3.50±0.05s    19.11  io.json.ToJSON.time_to_json_iso('values', 'df_td_int_ts')
+         184±9ms       3.43±0.08s    18.62  io.json.ToJSON.time_to_json_iso('records', 'df_td_int_ts')
+        363±10ms       3.70±0.05s    10.17  io.json.ToJSON.time_to_json_iso('columns', 'df_td')
+        375±10ms       3.70±0.05s     9.86  io.json.ToJSON.time_to_json_iso('index', 'df_td')
+        482±20ms       3.92±0.08s     8.13  io.json.ToJSON.time_to_json_iso('index', 'df_td_int_ts')
+         483±9ms       3.85±0.03s     7.96  io.json.ToJSON.time_to_json_iso('columns', 'df_td_int_ts')
+        116±10ms         482±30ms     4.16  io.json.ToJSON.time_to_json_iso('split', 'df_int_floats')
+        85.8±5ms         336±40ms     3.91  io.json.ToJSON.time_to_json_iso('values', 'df_int_floats')
+        120±10ms         455±30ms     3.80  io.json.ToJSON.time_to_json_iso('records', 'df_int_floats')
+        410±10ms         976±20ms     2.38  io.json.ToJSON.time_to_json_iso('index', 'df_int_floats')
+        420±10ms         982±20ms     2.34  io.json.ToJSON.time_to_json_iso('columns', 'df_int_floats')
```
Interestingly, there are some significant changes for int-float DataFrames as well.
I tried instead converting to pandas Timedelta in C which, performance-wise, is less bad than converting in Python,  but still not that great:
```
       before           after         ratio
     [6396bc37]       [b97525a0]
     <master>         <28256-iso-date-json>
+        72.0±1ms       2.28±0.05s    31.61  io.json.ToJSON.time_to_json_iso('records', 'df_td')
+        68.3±4ms       2.14±0.01s    31.27  io.json.ToJSON.time_to_json_iso('values', 'df_td')
+        87.7±3ms       2.19±0.03s    25.01  io.json.ToJSON.time_to_json_iso('split', 'df_td')
+         148±2ms       2.30±0.01s    15.55  io.json.ToJSON.time_to_json_iso('values', 'df_td_int_ts')
+         174±7ms       2.37±0.04s    13.65  io.json.ToJSON.time_to_json_iso('split', 'df_td_int_ts')
+        179±10ms       2.40±0.01s    13.40  io.json.ToJSON.time_to_json_iso('records', 'df_td_int_ts')
+         351±9ms       2.42±0.04s     6.92  io.json.ToJSON.time_to_json_iso('columns', 'df_td')
+        356±10ms       2.45±0.01s     6.87  io.json.ToJSON.time_to_json_iso('index', 'df_td')
+         449±7ms       2.65±0.07s     5.89  io.json.ToJSON.time_to_json_iso('index', 'df_td_int_ts')
+         471±8ms       2.50±0.01s     5.30  io.json.ToJSON.time_to_json_iso('columns', 'df_td_int_ts')
```
I wonder whether we can ever do much better than this without a function that formats NumPy timedeltas directly.
@cbertinato what is status of this?
Unless I'm missing another way to solve this, it looks like we take a performance hit.  So I suppose the question is whether this is tolerable for this fix, or whether we should trash this branch and go with a vectorized solution something like Will's work in #28863.
instead of this approach i would convert the timedeltas to longs (using vectorized methods on the series) before passing to the c based dumper
I think this should be easier to fix after #30283. I think will just need a new method for time delta to iso though
In C?
Right I think would be easier to do in C since the datetime code is already there
Sorry for the severe lag on this. Will pick it back up now that #30283 is in.
@cbertinato I think I'm close on a C impl actually. might be able to push up soon to compare
Thanks for the PR! I think will be superseded by #30903 though so closing for now