instance Enum DiffTime dangerous
ddssff opened this issue · comments
David Fox commented
As you probably know, there are 86,400,000,000,000,000 picoseconds in a day. This is a 57 bit integer, which is larger than the Int type on many machines. Therefore, when you say fromEnum diff you will get unpleasant results at most times of day.)
{-# LANGUAGE TypeApplications #-}
import Data.Time
main :: IO ()
main = do
mapM_ test
["2022-06-25 00:00:00.00001 UTC",
"2022-06-25 00:00:00.0001 UTC",
"2022-06-25 00:00:00.001 UTC",
"2022-06-25 00:00:00.002 UTC",
"2022-06-25 00:00:00.003 UTC",
"2022-06-25 00:00:27.581804038 UTC",
"2022-06-25 12:59:27.581804038 UTC",
"2022-06-25 23:59:27.581804038 UTC"]
where
test :: String -> IO ()
test s = do
putStrLn ("expected: " <> show (utctDayTime (read s :: UTCTime)))
putStrLn (" actual: " <> show (toEnum @DiffTime $ fromEnum $ utctDayTime (read s :: UTCTime)))
Output:
$ ghcjs test.hs -o test
[1 of 1] Compiling Main ( test.hs, test.js_o )
Linking test.jsexe (Main)
$ nodejs ./test.jsexe/all.js
expected: 0.00001s
actual: 0.00001s
expected: 0.0001s
actual: 0.0001s
expected: 0.001s
actual: 0.001s
expected: 0.002s
actual: 0.002s
expected: 0.003s
actual: -0.001294967296s
expected: 27.581804038s
actual: -0.000475936912s
expected: 46767.581804038s
actual: 0.000745473904s
expected: 86367.581804038s
actual: -0.00145057192s
Ashley Yakeley commented
Surely this is no more dangerous than instance Enum Integer
?
Prelude> fromEnum (10000000000000000000 :: Integer)
-8446744073709551616
David Fox commented
I'm not sure how much of a comfort this is. In my personal experience the DiffTime instance has actually caused a problem that I had to track down.
Ashley Yakeley commented
Don't use fromEnum
I guess?
Ashley Yakeley commented
Not seeing a change to be made here.