module Data.Hourglass.Types
(
NanoSeconds(..)
, Seconds(..)
, Month(..)
, WeekDay(..)
, TimezoneOffset(..)
, timezoneOffsetToSeconds
, Elapsed(..)
, ElapsedP(..)
, Date(..)
, TimeOfDay(..)
, DateTime(..)
) where
import Data.Int
import Data.Data
import Data.Ratio
import Control.DeepSeq
import Data.Hourglass.Utils (pad2)
newtype NanoSeconds = NanoSeconds Int
deriving (Read,Eq,Ord,Num,Data,Typeable,NFData)
instance Show NanoSeconds where
show (NanoSeconds v) = shows v "ns"
newtype Seconds = Seconds Int64
deriving (Read,Eq,Ord,Num,Data,Typeable,NFData)
instance Show Seconds where
show (Seconds s) = shows s "s"
newtype Elapsed = Elapsed Seconds
deriving (Read,Eq,Ord,Num,Data,Typeable,NFData)
instance Show Elapsed where
show (Elapsed s) = show s
data ElapsedP = ElapsedP !Elapsed !NanoSeconds
deriving (Read,Eq,Ord,Data,Typeable)
instance Show ElapsedP where
show (ElapsedP e ns) = shows e ('.' : show ns)
instance NFData ElapsedP where rnf e = e `seq` ()
instance Num ElapsedP where
(ElapsedP e1 ns1) + (ElapsedP e2 ns2) = ElapsedP (e1+e2) (ns1+ns2)
(ElapsedP e1 ns1) (ElapsedP e2 ns2) = ElapsedP (e1e2) (ns1ns2)
(ElapsedP e1 ns1) * (ElapsedP e2 ns2) = ElapsedP (e1*e2) (ns1*ns2)
negate (ElapsedP e ns) = ElapsedP (negate e) ns
abs (ElapsedP e ns) = ElapsedP (abs e) ns
signum (ElapsedP e ns) = ElapsedP (signum e) ns
fromInteger i = ElapsedP (Elapsed (fromIntegral i)) 0
instance Real ElapsedP where
toRational (ElapsedP (Elapsed (Seconds s)) (NanoSeconds ns)) =
fromIntegral s + (1000000000 % fromIntegral ns)
data Month =
January
| February
| March
| April
| May
| June
| July
| August
| September
| October
| November
| December
deriving (Show,Eq,Ord,Enum,Data,Typeable)
data WeekDay =
Sunday
| Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
deriving (Show,Read,Eq,Ord,Enum,Data,Typeable)
newtype TimezoneOffset = TimezoneOffset
{ timezoneOffsetToMinutes :: Int
} deriving (Eq,Ord,Data,Typeable)
timezoneOffsetToSeconds :: TimezoneOffset -> Seconds
timezoneOffsetToSeconds (TimezoneOffset ofs) = Seconds (fromIntegral ofs * 60)
instance Show TimezoneOffset where
show (TimezoneOffset tz) =
concat [(if tz < 0 then "-" else "+"), pad2 tzH, pad2 tzM]
where (tzH, tzM) = abs tz `divMod` 60
data Date = Date
{ dateYear :: !Int
, dateMonth :: !Month
, dateDay :: !Int
} deriving (Show,Eq,Ord,Data,Typeable)
instance NFData Date where
rnf (Date y m d) = y `seq` m `seq` d `seq` ()
data TimeOfDay = TimeOfDay
{ todHour :: !Int
, todMin :: !Int
, todSec :: !Int
, todNSec :: !NanoSeconds
} deriving (Show,Eq,Ord,Data,Typeable)
instance NFData TimeOfDay where
rnf (TimeOfDay h m s ns) = h `seq` m `seq` s `seq` ns `seq` ()
data DateTime = DateTime
{ dtDate :: Date
, dtTime :: TimeOfDay
} deriving (Show,Eq,Ord,Data,Typeable)
instance NFData DateTime where
rnf (DateTime d t) = rnf d `seq` rnf t `seq` ()