Instruction time and distance don't match to path details time and distance

Thanks for the detailed description, this sounds like two bugs.

Regarding the bug with the distance&time mismatch - can you try?

--- a/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java
+++ b/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java
@@ -32,8 +32,8 @@ public class DistanceDetails extends AbstractPathDetailsBuilder {
 
     @Override
     public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) {
-        if (edge.getEdge() != edgeId) {
-            edgeId = edge.getEdge();
+        if (edge.getEdgeKey() != edgeId) {
+            edgeId = edge.getEdgeKey();

similar for the TimeDetails.

best.time=120864
instructions.time=100864 # turn cost is 20 seconds

This might be a known (and different) bug, see the discussion here: ResponsePath time not equal sum instruction times? - #3 by Juan_Pablo_Lopez )

For this, if you like, you can try the following patch:

--- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
+++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
@@ -430,8 +430,10 @@ public class InstructionsFromEdges implements Path.EdgeVisitor {
         }
         double newDist = edge.getDistance();
         prevInstruction.setDistance(newDist + prevInstruction.getDistance());
-        // todo: why do we not account for turn times here ?
-        prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime());
+        if (prevEdge != null)
+            prevInstruction.setTime(GHUtility.calcMillisWithTurnMillis(weighting, edge, false, prevEdge.getEdge()) + prevInstruction.getTime());
+        else
+            prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime());

btw: I highly recommend against using the shortest weighting for car (use the custom weighting with a high distance influence instead). Maybe we should better remove the shortest.