import App.Clk.Entry
import App.Clk.Util
import Data.List
import Data.Time.Clock
import Data.Time.LocalTime

main = do
    tz     <- getCurrentTimeZone
    entries <- mostRecentMonthEntries
    putStrLn $ intercalate "\n" $ map (showUser tz) $ entries

showUser :: TimeZone -> Entry -> String
showUser tz (Entry name time tags msg dur) = intercalate "\t" parts
    where parts = [ userTime, durS, tagsS, msg ]
          userTime = strftime "%m/%d %H:%M" $ utcToLocalTime tz time
          tagsS    = intercalate "," tags
          durS     = maybe "" showDur dur

showDur :: NominalDiffTime -> String
showDur dur = case dur of
            x | x <       60 -> show (round x) ++ "s"
              | x <    60*60 -> show (round (x/60)) ++ "m"
              | x < 24*60*60 -> show (round (x/60/60)) ++ "h"
            x                -> show (round (x/24/60/60)) ++ "d"

import App.Clk.Entry
import App.Clk.Util
import Data.List
import Data.Time.Clock
import Data.Time.LocalTime

main = do
    tz     <- getCurrentTimeZone
    entries <- mostRecentMonthEntries
    putStrLn $ intercalate "\n" $ map (showUser tz) $ entries

showUser :: TimeZone -> Entry -> String
showUser tz (Entry name time tags msg dur) = intercalate "\t" parts
    where parts = [ userTime, durS, tagsS, msg ]
          userTime = strftime "%m/%d %H:%M" $ utcToLocalTime tz time
          tagsS    = intercalate "," tags
          durS     = maybe "" showDur dur

showDur :: NominalDiffTime -> String
showDur dur = case dur of
            x | x <       60 -> show (round x) ++ "s"
              | x <    60*60 -> show (round (x/60)) ++ "m"
              | x < 24*60*60 -> show (round (x/60/60)) ++ "h"
              | otherwise    -> show (round (x/24/60/60)) ++ "d"

Use 'otherwise' in a guard statement
Use 'otherwise' in a guard statement

I suppose this is the proper way to implement this bit of code.  Using
'otherwise' seems cleaner since it doesn't require duplicating a
variable name and it clearly shows the fall through, default state.
