8

I'm surprised nobody has asked this before, but... How do I trivially print a NominalDiffTime as hours, minutes and seconds? (And possibly days, if it happens to be that long...)

For reasons unknown, the Show instance prints total seconds, which is obviously useless. (How long is 13,055.22 seconds? Is that a few minutes? A day? Half an hour? I have no idea!)

There's the FormatTime class, but it doesn't apply to NominalDiffTime.

It seems you can use the floor method to get total seconds as an actual number, but then what do you do with it?

As far as I can tell, DiffTime doesn't help either.

There must be a way to print time durations sanely...

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220

4 Answers4

4

You can print a DiffTime -- which actually represents a duration, and is likely the type you should be using -- by going through TimeOfDay. Getting your hands on a DiffTime correctly is actually a little bit tricky; you'll need:

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • Note that this only works for `DiffTime`s of less than a day, if it's more than a day `timeToTimeOfDay` adds the extra time as leap seconds. The question asked about a solution that works for days too. – xnyhps Jun 29 '15 at 06:34
1

floor[1] gives you (as you say) the number of seconds, which you can then use div and mod to convert into hours, minutes and seconds.

For example:

floor ndt `div` 60 -- minutes, which may be more than 59
floor ndt `mod` 60 -- seconds

[1] unlike fromEnum, which is a "conversion function" but doesn't convert to seconds, contrary to what the documentation says.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
1
myFormatDiffTime :: NominalDiffTime -> String
myFormatDiffTime = formatTime defaultTimeLocale "%H:%M:%S" . posixSecondsToUTCTime
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
1

time-1.10 has formatTime support for NominalDiffTime.

formatTime defaultTimeLocale "%H:%M:%S" ndt