diff --git a/formatting.cabal b/formatting.cabal
--- a/formatting.cabal
+++ b/formatting.cabal
@@ -1,5 +1,5 @@
 name:                formatting
-version:             3.1.4
+version:             4.0
 synopsis:            Combinator-based type-safe formatting (like printf() or FORMAT)
 description:         Combinator-based type-safe formatting (like printf() or FORMAT), modelled from the HoleyMonoids package.
 license:             BSD3
diff --git a/src/Formatting/Time.hs b/src/Formatting/Time.hs
--- a/src/Formatting/Time.hs
+++ b/src/Formatting/Time.hs
@@ -217,19 +217,22 @@
 weekOfYearMon :: FormatTime a => Format a
 weekOfYearMon = later (build . fmt "%W")
 
--- | Display a time span as one time relative to another. Equiv. to
--- (t1 - t2) for some (t1,t2) pair.
-diff :: Bool                      -- ^ Display 'in/ago'?
-     -> Format (UTCTime, UTCTime) -- ^ Example: '3 seconds ago', 'in three days'.
+-- * Time spans, diffs, 'NominalDiffTime', 'DiffTime', etc.
+
+-- | Display a time span as one time relative to another. Input is
+-- assumed to be seconds. Typical inputs are 'NominalDiffTime' and
+-- 'DiffTime'.
+diff :: (RealFrac n)
+     => Bool     -- ^ Display 'in/ago'?
+     -> Format n -- ^ Example: '3 seconds ago', 'in three days'.
 diff fix =
-  later (fromLazyText . diffed)
+  later diffed
   where
-    diffed (t1,t2) =
+    diffed ts =
       case find (\(s,_,_) -> abs ts >= s) (reverse ranges) of
         Nothing -> "unknown"
-        Just (_,f,base) -> format (prefix % f % suffix) (toInt ts base)
-      where ts = diffUTCTime t1 t2
-            prefix = now (if fix && ts > 0 then "in " else "")
+        Just (_,f,base) -> bprint (prefix % f % suffix) (toInt ts base)
+      where prefix = now (if fix && ts > 0 then "in " else "")
             suffix = now (if fix && ts < 0 then " ago" else "")
     toInt ts base = abs (round (ts / base))
     ranges =
@@ -256,6 +259,41 @@
             day = hour * 24
             hour = minute * 60
             minute = 60
+
+-- | Display the absolute value time span in years.
+years :: (RealFrac n)
+      => Int -- ^ Decimal places.
+      -> Format n
+years n = later (bprint (fixed n) . abs . count)
+  where count n = n / 365 / 24 / 60 / 60
+
+-- | Display the absolute value time span in days.
+days :: (RealFrac n)
+      => Int -- ^ Decimal places.
+      -> Format n
+days n = later (bprint (fixed n) . abs . count)
+  where count n = n / 24 / 60 / 60
+
+-- | Display the absolute value time span in hours.
+hours :: (RealFrac n)
+      => Int -- ^ Decimal places.
+      -> Format n
+hours n = later (bprint (fixed n) . abs . count)
+  where count n = n / 60 / 60
+
+-- | Display the absolute value time span in minutes.
+minutes :: (RealFrac n)
+      => Int -- ^ Decimal places.
+      -> Format n
+minutes n = later (bprint (fixed n) . abs . count)
+  where count n = n / 60
+
+-- | Display the absolute value time span in seconds.
+seconds :: (RealFrac n)
+      => Int -- ^ Decimal places.
+      -> Format n
+seconds n = later (bprint (fixed n) . abs . count)
+  where count n = n
 
 -- * Internal.
 
