diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,15 @@
 
 ## Unreleased
 
+## 0.3.0.3
+
+* Add 'ContainerOptions' type to `Test.Sandwich.Contexts.Container`
+* Improve display of setup/work/teardown in TUI
+
+## 0.3.0.2
+
 * Re-fix compatibility for base < 4.14.0.0
+* windows: fix Infinity -> maxBound for an Int
 
 ## 0.3.0.1
 
diff --git a/sandwich.cabal b/sandwich.cabal
--- a/sandwich.cabal
+++ b/sandwich.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           sandwich
-version:        0.3.0.2
+version:        0.3.0.3
 synopsis:       Yet another test framework for Haskell
 description:    Please see the <https://codedownio.github.io/sandwich documentation>.
 category:       Testing
diff --git a/src/Test/Sandwich/Formatters/TerminalUI/Draw.hs b/src/Test/Sandwich/Formatters/TerminalUI/Draw.hs
--- a/src/Test/Sandwich/Formatters/TerminalUI/Draw.hs
+++ b/src/Test/Sandwich/Formatters/TerminalUI/Draw.hs
@@ -76,8 +76,8 @@
                       , str "]"]
       , Just $ padRight Max $ withAttr toggleMarkerAttr $ str (if toggled then " [-]" else " [+]")
       , if not (app ^. appShowRunTimes) then Nothing else case status of
-          Running {..} -> Just $ getRunTimes app statusStartTime (app ^. appCurrentTime) statusSetupTime Nothing True
-          Done {..} -> Just $ getRunTimes app statusStartTime statusEndTime statusSetupTime statusTeardownTime False
+          Running {..} -> Just $ getRunTimes app statusStartTime statusSetupFinishTime statusTeardownStartTime (app ^. appCurrentTime) True
+          Done {..} -> Just $ getRunTimes app statusStartTime statusSetupFinishTime statusTeardownStartTime statusEndTime False
           _ -> Nothing
       ]
 
diff --git a/src/Test/Sandwich/Formatters/TerminalUI/Draw/RunTimes.hs b/src/Test/Sandwich/Formatters/TerminalUI/Draw/RunTimes.hs
--- a/src/Test/Sandwich/Formatters/TerminalUI/Draw/RunTimes.hs
+++ b/src/Test/Sandwich/Formatters/TerminalUI/Draw/RunTimes.hs
@@ -1,5 +1,8 @@
+{-# LANGUAGE MultiWayIf #-}
 
-module Test.Sandwich.Formatters.TerminalUI.Draw.RunTimes (getRunTimes) where
+module Test.Sandwich.Formatters.TerminalUI.Draw.RunTimes (
+  getRunTimes
+  ) where
 
 import Brick
 import Data.Maybe
@@ -16,20 +19,36 @@
 minGray = 50
 maxGray = 255
 
-getRunTimes :: AppState -> UTCTime -> UTCTime -> Maybe NominalDiffTime -> Maybe NominalDiffTime -> Bool -> Widget n
-getRunTimes app startTime endTime statusSetupTime statusTeardownTime showEllipses = raw setupWork <+> raw actualWork <+> raw teardownWork
+data Mode =
+  NothingRunning
+  | SetupRunning
+  | WorkRunning
+  | TeardownRunning
+  deriving (Eq)
+
+getRunTimes :: AppState -> UTCTime -> Maybe UTCTime -> Maybe UTCTime -> UTCTime -> Bool -> Widget n
+getRunTimes app startTime statusSetupFinishTime statusTeardownStartTime endTime showEllipses = raw setupWork <+> raw actualWork <+> raw teardownWork
   where
     totalElapsed = diffUTCTime (app ^. appCurrentTime) (app ^. appStartTime)
 
-    actualWorkTime = (diffUTCTime endTime startTime) - (fromMaybe 0 statusSetupTime) - (fromMaybe 0 statusTeardownTime)
+    setupTime = diffUTCTime <$> statusSetupFinishTime <*> pure startTime
+    teardownTime = diffUTCTime <$> pure endTime <*> statusTeardownStartTime
 
-    setupWork = maybe mempty (\dt -> V.string (getAttr totalElapsed dt) [i|(#{formatNominalDiffTime dt}) + |]) statusSetupTime
-    actualWork = V.string (getAttr totalElapsed actualWorkTime) (formatNominalDiffTime actualWorkTime <> (if showEllipses then "..." else ""))
-    teardownWork = maybe mempty (\dt -> V.string (getAttr totalElapsed dt) [i| + (#{formatNominalDiffTime dt})|]) statusTeardownTime
+    actualWorkTime = (diffUTCTime endTime startTime) - (fromMaybe 0 setupTime) - (fromMaybe 0 teardownTime)
 
-getAttr :: NominalDiffTime -> NominalDiffTime -> V.Attr
-getAttr totalElapsed dt = V.Attr {
-  V.attrStyle = V.Default
+    mode = if
+      | not showEllipses -> NothingRunning
+      | isJust statusTeardownStartTime -> TeardownRunning
+      | isJust statusSetupFinishTime -> WorkRunning
+      | otherwise -> SetupRunning
+
+    setupWork = maybe mempty (\dt -> V.string (getAttr totalElapsed dt (mode == SetupRunning)) [i|(#{formatNominalDiffTime dt}) + |]) setupTime
+    actualWork = V.string (getAttr totalElapsed actualWorkTime (mode == WorkRunning)) (formatNominalDiffTime actualWorkTime)
+    teardownWork = maybe mempty (\dt -> V.string (getAttr totalElapsed dt (mode == TeardownRunning)) [i| + (#{formatNominalDiffTime dt})|]) teardownTime
+
+getAttr :: NominalDiffTime -> NominalDiffTime -> Bool -> V.Attr
+getAttr totalElapsed dt bold = V.Attr {
+  V.attrStyle = if bold then (V.SetTo V.bold) else V.Default
   , V.attrForeColor = V.SetTo $ grayAt $ getLevel (realToFrac totalElapsed) (realToFrac dt)
   , V.attrBackColor = V.Default
   , V.attrURL = V.Default
diff --git a/src/Test/Sandwich/Formatters/TerminalUI/Draw/ToBrickWidget.hs b/src/Test/Sandwich/Formatters/TerminalUI/Draw/ToBrickWidget.hs
--- a/src/Test/Sandwich/Formatters/TerminalUI/Draw/ToBrickWidget.hs
+++ b/src/Test/Sandwich/Formatters/TerminalUI/Draw/ToBrickWidget.hs
@@ -5,7 +5,6 @@
 
 import Brick
 import Brick.Widgets.Border
-import UnliftIO.Exception
 import Control.Monad.Reader
 import qualified Data.List as L
 import Data.Maybe
@@ -20,6 +19,7 @@
 import Test.Sandwich.Types.RunTree
 import Test.Sandwich.Types.Spec
 import Text.Show.Pretty as P
+import UnliftIO.Exception
 
 
 class ToBrickWidget a where
@@ -28,10 +28,10 @@
 instance ToBrickWidget Status where
   toBrickWidget (NotStarted {}) = return $ strWrap "Not started."
   toBrickWidget (Running {statusStartTime}) = return $ strWrap [i|Started at #{statusStartTime}.|]
-  toBrickWidget (Done startTime endTime setupTime teardownTime Success) = return $ strWrap ([i|Succeeded in #{showTimeDiff startTime endTime}.#{setupTeardownInfo}|])
+  toBrickWidget (Done startTime setupFinishTime teardownStartTime endTime Success) = return $ strWrap ([i|Succeeded in #{showTimeDiff startTime endTime}.#{setupTeardownInfo}|])
     where
-      setupInfo :: Maybe T.Text = (\t -> [i|Setup: #{formatNominalDiffTime t}.|]) <$> setupTime
-      teardownInfo :: Maybe T.Text = (\t -> [i|Teardown: #{formatNominalDiffTime t}.|]) <$> teardownTime
+      setupInfo :: Maybe T.Text = (\t -> [i|Setup: #{formatNominalDiffTime t}.|]) <$> (flip diffUTCTime startTime <$> setupFinishTime)
+      teardownInfo :: Maybe T.Text = (\t -> [i|Teardown: #{formatNominalDiffTime t}.|]) <$> (diffUTCTime endTime <$> teardownStartTime)
       setupTeardownInfo = case catMaybes [setupInfo, teardownInfo] of
         [] -> ""
         xs -> " (" <> T.intercalate " " xs <> ")"
diff --git a/src/Test/Sandwich/Golden.hs b/src/Test/Sandwich/Golden.hs
--- a/src/Test/Sandwich/Golden.hs
+++ b/src/Test/Sandwich/Golden.hs
@@ -8,14 +8,14 @@
   -- * Main test function
   golden
 
-  -- * Built-in Goldens.
+  -- * Built-in Goldens
   , goldenText
   , goldenString
   , goldenJSON
   , goldenShowable
   , mkGolden
 
-  -- * Parameters for a 'Golden'.
+  -- * Parameters for a 'Golden'
   , goldenOutput
   , goldenWriteToFile
   , goldenReadFromFile
diff --git a/src/Test/Sandwich/Interpreters/StartTree.hs b/src/Test/Sandwich/Interpreters/StartTree.hs
--- a/src/Test/Sandwich/Interpreters/StartTree.hs
+++ b/src/Test/Sandwich/Interpreters/StartTree.hs
@@ -10,7 +10,6 @@
 
 import Control.Concurrent.Async
 import Control.Concurrent.MVar
-import Control.Concurrent.STM
 import Control.Monad
 import Control.Monad.IO.Class
 import Control.Monad.Logger
@@ -41,6 +40,7 @@
 import Test.Sandwich.Types.TestTimer
 import Test.Sandwich.Util
 import UnliftIO.Exception
+import UnliftIO.STM
 
 
 baseContextFromCommon :: RunNodeCommonWithStatus s l t -> BaseContext -> BaseContext
@@ -53,20 +53,20 @@
   let ctx = modifyBaseContext ctx' $ baseContextFromCommon runNodeCommon
   runInAsync node ctx $ do
     (timed (runExampleM runNodeBefore ctx runTreeLogs (Just [i|Exception in before '#{runTreeLabel}' handler|]))) >>= \case
-      (result@(Failure fr@(Pending {})), setupTime) -> do
+      (result@(Failure fr@(Pending {})), _setupStartTime, setupFinishTime) -> do
         markAllChildrenWithResult runNodeChildren ctx (Failure fr)
-        return (result, mkSetupTimingInfo setupTime)
-      (result@(Failure fr), setupTime) -> do
+        return (result, mkSetupTimingInfo setupFinishTime)
+      (result@(Failure fr), _setupStartTime, setupFinishTime) -> do
         markAllChildrenWithResult runNodeChildren ctx (Failure $ GetContextException Nothing (SomeExceptionWithEq $ toException fr))
-        return (result, mkSetupTimingInfo setupTime)
-      (Success, setupTime) -> do
+        return (result, mkSetupTimingInfo setupFinishTime)
+      (Success, _setupStartTime, setupFinishTime) -> do
         void $ runNodesSequentially runNodeChildren ctx
-        return (Success, mkSetupTimingInfo setupTime)
-      (Cancelled, setupTime) -> do
-        return (Cancelled, mkSetupTimingInfo setupTime)
-      (DryRun, setupTime) -> do
+        return (Success, mkSetupTimingInfo setupFinishTime)
+      (Cancelled, _setupStartTime, setupFinishTime) -> do
+        return (Cancelled, mkSetupTimingInfo setupFinishTime)
+      (DryRun, _setupStartTime, setupFinishTime) -> do
         void $ runNodesSequentially runNodeChildren ctx
-        return (DryRun, mkSetupTimingInfo setupTime)
+        return (DryRun, mkSetupTimingInfo setupFinishTime)
 startTree node@(RunNodeAfter {..}) ctx' = do
   let RunNodeCommonWithStatus {..} = runNodeCommon
   let ctx = modifyBaseContext ctx' $ baseContextFromCommon runNodeCommon
@@ -74,8 +74,8 @@
     result <- liftIO $ newIORef (Success, emptyExtraTimingInfo)
     finally (void $ runNodesSequentially runNodeChildren ctx)
             (do
-                (ret, dt) <- timed (runExampleM runNodeAfter ctx runTreeLogs (Just [i|Exception in after '#{runTreeLabel}' handler|]))
-                writeIORef result (ret, mkTeardownTimingInfo dt)
+                (ret, teardownStartTime, _teardownFinishTime) <- timed (runExampleM runNodeAfter ctx runTreeLogs (Just [i|Exception in after '#{runTreeLabel}' handler|]))
+                writeIORef result (ret, mkTeardownTimingInfo teardownStartTime)
             )
     liftIO $ readIORef result
 startTree node@(RunNodeIntroduce {..}) ctx' = do
@@ -87,27 +87,31 @@
                 let asyncExceptionResult e = Failure $ GotAsyncException Nothing (Just [i|introduceWith #{runTreeLabel} alloc handler got async exception|]) (SomeAsyncExceptionWithEq e)
                 flip withException (\(e :: SomeAsyncException) -> markAllChildrenWithResult runNodeChildrenAugmented ctx (asyncExceptionResult e)) $
                   timed (runExampleM' runNodeAlloc ctx runTreeLogs (Just [i|Failure in introduce '#{runTreeLabel}' allocation handler|])))
-            (\(ret, setupTime) -> case ret of
-                Left failureReason -> writeIORef result (Failure failureReason, mkSetupTimingInfo setupTime)
+            (\(ret, setupStartTime, setupFinishTime) -> case ret of
+                Left failureReason -> writeIORef result (Failure failureReason, mkSetupTimingInfo setupStartTime)
                 Right intro -> do
-                  (ret', teardownTime) <- timed $ runExampleM (runNodeCleanup intro) ctx runTreeLogs (Just [i|Failure in introduce '#{runTreeLabel}' cleanup handler|])
-                  writeIORef result (ret', ExtraTimingInfo (Just setupTime) (Just teardownTime))
+                  teardownStartTime <- getCurrentTime
+                  addTeardownStartTimeToStatus runTreeStatus teardownStartTime
+                  ret' <- runExampleM (runNodeCleanup intro) ctx runTreeLogs (Just [i|Failure in introduce '#{runTreeLabel}' cleanup handler|])
+                  writeIORef result (ret', ExtraTimingInfo (Just setupFinishTime) (Just teardownStartTime))
             )
-            (\(ret, _setupTime) -> case ret of
-                Left failureReason@(Pending {}) -> do
-                  -- TODO: add note about failure in allocation
-                  markAllChildrenWithResult runNodeChildrenAugmented ctx (Failure failureReason)
-                Left failureReason -> do
-                  -- TODO: add note about failure in allocation
-                  markAllChildrenWithResult runNodeChildrenAugmented ctx (Failure $ GetContextException Nothing (SomeExceptionWithEq $ toException failureReason))
-                Right intro -> do
-                  -- Special hack to modify the test timer profile via an introduce, without needing to track it everywhere.
-                  -- It would be better to track the profile at the type level
-                  let ctxFinal = case cast intro of
-                        Just (TestTimerProfile t) -> modifyBaseContext ctx (\bc -> bc { baseContextTestTimerProfile = t })
-                        Nothing -> ctx
+            (\(ret, _setupStartTime, setupFinishTime) -> do
+                addSetupFinishTimeToStatus runTreeStatus setupFinishTime
+                case ret of
+                  Left failureReason@(Pending {}) -> do
+                    -- TODO: add note about failure in allocation
+                    markAllChildrenWithResult runNodeChildrenAugmented ctx (Failure failureReason)
+                  Left failureReason -> do
+                    -- TODO: add note about failure in allocation
+                    markAllChildrenWithResult runNodeChildrenAugmented ctx (Failure $ GetContextException Nothing (SomeExceptionWithEq $ toException failureReason))
+                  Right intro -> do
+                    -- Special hack to modify the test timer profile via an introduce, without needing to track it everywhere.
+                    -- It would be better to track the profile at the type level
+                    let ctxFinal = case cast intro of
+                          Just (TestTimerProfile t) -> modifyBaseContext ctx (\bc -> bc { baseContextTestTimerProfile = t })
+                          Nothing -> ctx
 
-                  void $ runNodesSequentially runNodeChildrenAugmented ((LabelValue intro) :> ctxFinal)
+                    void $ runNodesSequentially runNodeChildrenAugmented ((LabelValue intro) :> ctxFinal)
             )
     readIORef result
 startTree node@(RunNodeIntroduceWith {..}) ctx' = do
@@ -121,25 +125,24 @@
                 _ -> Failure $ Reason Nothing [i|introduceWith '#{runTreeLabel}' handler threw exception|]
           flip withException (\e -> recordExceptionInStatus runTreeStatus e >> markAllChildrenWithResult runNodeChildrenAugmented ctx (failureResult e)) $ do
             beginningCleanupVar <- liftIO $ newIORef Nothing
-            startTime <- liftIO getCurrentTime
             results <- runNodeIntroduceAction $ \intro -> do
-              afterMakingIntroTime <- liftIO getCurrentTime
-              let setupTime = diffUTCTime afterMakingIntroTime startTime
+              setupFinishTime <- liftIO getCurrentTime
+              addSetupFinishTimeToStatus runTreeStatus setupFinishTime
 
               results <- liftIO $ runNodesSequentially runNodeChildrenAugmented ((LabelValue intro) :> ctx)
 
-              beginningCleanupTs <- liftIO getCurrentTime
-              liftIO $ writeIORef beginningCleanupVar (Just beginningCleanupTs)
+              teardownStartTime <- liftIO getCurrentTime
+              addTeardownStartTimeToStatus runTreeStatus teardownStartTime
+              liftIO $ writeIORef beginningCleanupVar (Just teardownStartTime)
 
-              liftIO $ writeIORef didRunWrappedAction (Right results, mkSetupTimingInfo setupTime)
+              liftIO $ writeIORef didRunWrappedAction (Right results, mkSetupTimingInfo setupFinishTime)
               return results
 
-            endTime <- liftIO getCurrentTime
             liftIO (readIORef beginningCleanupVar) >>= \case
               Nothing -> return ()
-              Just beginningCleanupTs ->
+              Just teardownStartTime ->
                 liftIO $ modifyIORef' didRunWrappedAction $
-                  \(ret, timingInfo) -> (ret, timingInfo { teardownTime = Just (diffUTCTime endTime beginningCleanupTs) })
+                  \(ret, timingInfo) -> (ret, timingInfo { teardownStartTime = Just teardownStartTime })
 
             return results
 
@@ -159,12 +162,11 @@
                 Just fr@(Pending {}) -> Failure fr
                 _ -> Failure $ Reason Nothing [i|around '#{runTreeLabel}' handler threw exception|]
           flip withException (\e -> recordExceptionInStatus runTreeStatus e >> markAllChildrenWithResult runNodeChildren ctx (failureResult e)) $ do
-            startTime <- liftIO getCurrentTime
             runNodeActionWith $ do
-              setupEndTime <- liftIO getCurrentTime
-              let setupTime = diffUTCTime setupEndTime startTime
+              setupFinishTime <- liftIO getCurrentTime
+              addSetupFinishTimeToStatus runTreeStatus setupFinishTime
               results <- liftIO $ runNodesSequentially runNodeChildren ctx
-              liftIO $ writeIORef didRunWrappedAction (Right results, mkSetupTimingInfo setupTime)
+              liftIO $ writeIORef didRunWrappedAction (Right results, mkSetupTimingInfo setupFinishTime)
               return results
 
           (liftIO $ readIORef didRunWrappedAction) >>= \case
@@ -206,7 +208,7 @@
       readMVar mvar
       (result, extraTimingInfo) <- timerFn action
       endTime <- liftIO getCurrentTime
-      liftIO $ atomically $ writeTVar runTreeStatus $ Done startTime endTime (setupTime extraTimingInfo) (teardownTime extraTimingInfo) result
+      liftIO $ atomically $ writeTVar runTreeStatus $ Done startTime (setupFinishTime extraTimingInfo) (teardownStartTime extraTimingInfo) endTime result
 
       whenFailure result $ \reason -> do
         -- Make sure the folder exists, if configured
@@ -260,7 +262,7 @@
               printLogs runTreeLogs
 
       return result
-  liftIO $ atomically $ writeTVar runTreeStatus $ Running startTime Nothing myAsync
+  liftIO $ atomically $ writeTVar runTreeStatus $ Running startTime Nothing Nothing myAsync
   liftIO $ putMVar mvar ()
   return myAsync  -- TODO: fix race condition with writing to runTreeStatus (here and above)
 
@@ -282,7 +284,10 @@
 markAllChildrenWithResult children baseContext status = do
   now <- liftIO getCurrentTime
   forM_ (L.filter (shouldRunChild' baseContext) $ concatMap getCommons children) $ \child ->
-    liftIO $ atomically $ writeTVar (runTreeStatus child) (Done now now Nothing Nothing status)
+    liftIO $ atomically $ modifyTVar (runTreeStatus child) $ \case
+      Running {..} -> Done now statusSetupFinishTime statusTeardownStartTime now status
+      done@(Done {}) -> done { statusResult = status }
+      _ -> Done now Nothing Nothing now status
 
 cancelAllChildrenWith :: [RunNode context] -> SomeAsyncException -> IO ()
 cancelAllChildrenWith children e = do
@@ -292,7 +297,7 @@
       NotStarted -> do
         now <- getCurrentTime
         let reason = GotAsyncException Nothing Nothing (SomeAsyncExceptionWithEq e)
-        atomically $ writeTVar (runTreeStatus $ runNodeCommon node) (Done now now Nothing Nothing (Failure reason))
+        atomically $ writeTVar (runTreeStatus $ runNodeCommon node) (Done now Nothing Nothing now (Failure reason))
       _ -> return ()
 
 shouldRunChild :: (HasBaseContext ctx) => ctx -> RunNodeWithStatus context s l t -> Bool
@@ -343,6 +348,18 @@
         Just (SomeExceptionWithCallStack e' cs) -> GotException (Just cs) msg (SomeExceptionWithEq (SomeException e'))
         _ -> GotException Nothing msg (SomeExceptionWithEq e)
 
+addSetupFinishTimeToStatus :: (MonadIO m) => TVar Status -> UTCTime -> m ()
+addSetupFinishTimeToStatus statusVar setupFinishTime = atomically $ modifyTVar statusVar $ \case
+  status@(Running {}) -> status { statusSetupFinishTime = Just setupFinishTime }
+  status@(Done {}) -> status { statusSetupFinishTime = Just setupFinishTime }
+  x -> x
+
+addTeardownStartTimeToStatus :: (MonadIO m) => TVar Status -> UTCTime -> m ()
+addTeardownStartTimeToStatus statusVar t = atomically $ modifyTVar statusVar $ \case
+  status@(Running {}) -> status { statusTeardownStartTime = Just t }
+  status@(Done {}) -> status { statusTeardownStartTime = Just t }
+  x -> x
+
 recordExceptionInStatus :: (MonadIO m) => TVar Status -> SomeException -> m ()
 recordExceptionInStatus status e = do
   endTime <- liftIO getCurrentTime
@@ -352,12 +369,12 @@
           Just (e' :: FailureReason) -> Failure e'
           _ -> Failure (GotException Nothing Nothing (SomeExceptionWithEq e))
   liftIO $ atomically $ modifyTVar status $ \case
-    Running {statusStartTime, statusSetupTime} -> Done statusStartTime endTime statusSetupTime Nothing ret
-    _ -> Done endTime endTime Nothing Nothing ret
+    Running {..} -> Done statusStartTime statusSetupFinishTime statusTeardownStartTime endTime ret
+    _ -> Done endTime Nothing Nothing endTime ret
 
-timed :: (MonadIO m) => m a -> m (a, NominalDiffTime)
+timed :: (MonadIO m) => m a -> m (a, UTCTime, UTCTime)
 timed action = do
   startTime <- liftIO getCurrentTime
   ret <- action
   endTime <- liftIO getCurrentTime
-  pure (ret, diffUTCTime endTime startTime)
+  pure (ret, startTime, endTime)
diff --git a/src/Test/Sandwich/Shutdown.hs b/src/Test/Sandwich/Shutdown.hs
--- a/src/Test/Sandwich/Shutdown.hs
+++ b/src/Test/Sandwich/Shutdown.hs
@@ -13,5 +13,5 @@
   Running {..} -> cancel statusAsync
   NotStarted -> do
     now <- getCurrentTime
-    atomically $ writeTVar (runTreeStatus $ runNodeCommon node) (Done now now Nothing Nothing Cancelled)
+    atomically $ writeTVar (runTreeStatus $ runNodeCommon node) (Done now Nothing Nothing now Cancelled)
   Done {} -> return ()
diff --git a/src/Test/Sandwich/Types/RunTree.hs b/src/Test/Sandwich/Types/RunTree.hs
--- a/src/Test/Sandwich/Types/RunTree.hs
+++ b/src/Test/Sandwich/Types/RunTree.hs
@@ -30,12 +30,13 @@
 
 data Status = NotStarted
             | Running { statusStartTime :: UTCTime
-                      , statusSetupTime :: Maybe NominalDiffTime
+                      , statusSetupFinishTime :: Maybe UTCTime
+                      , statusTeardownStartTime :: Maybe UTCTime
                       , statusAsync :: Async Result }
             | Done { statusStartTime :: UTCTime
+                   , statusSetupFinishTime :: Maybe UTCTime
+                   , statusTeardownStartTime :: Maybe UTCTime
                    , statusEndTime :: UTCTime
-                   , statusSetupTime :: Maybe NominalDiffTime
-                   , statusTeardownTime :: Maybe NominalDiffTime
                    , statusResult :: Result }
             deriving (Show, Eq)
 
diff --git a/src/Test/Sandwich/Types/Spec.hs b/src/Test/Sandwich/Types/Spec.hs
--- a/src/Test/Sandwich/Types/Spec.hs
+++ b/src/Test/Sandwich/Types/Spec.hs
@@ -87,18 +87,18 @@
   deriving (Show, Eq)
 
 data ExtraTimingInfo = ExtraTimingInfo {
-  setupTime :: Maybe NominalDiffTime
-  , teardownTime :: Maybe NominalDiffTime
+  setupFinishTime :: Maybe UTCTime
+  , teardownStartTime :: Maybe UTCTime
   }
 
 emptyExtraTimingInfo :: ExtraTimingInfo
 emptyExtraTimingInfo = ExtraTimingInfo Nothing Nothing
 
-mkSetupTimingInfo :: NominalDiffTime -> ExtraTimingInfo
-mkSetupTimingInfo dt = ExtraTimingInfo (Just dt) Nothing
+mkSetupTimingInfo :: UTCTime -> ExtraTimingInfo
+mkSetupTimingInfo setupFinishTime = ExtraTimingInfo (Just setupFinishTime) Nothing
 
-mkTeardownTimingInfo :: NominalDiffTime -> ExtraTimingInfo
-mkTeardownTimingInfo dt = ExtraTimingInfo Nothing (Just dt)
+mkTeardownTimingInfo :: UTCTime -> ExtraTimingInfo
+mkTeardownTimingInfo teardownStartTime = ExtraTimingInfo Nothing (Just teardownStartTime)
 
 data ShowEqBox = forall s. (Show s, Eq s) => SEB s
 instance Show ShowEqBox where show (SEB x) = show x
