module Data.Time.LocalTime.Internal.TimeOfDay
(
TimeOfDay(..)
, midnight
, midday
, makeTimeOfDayValid
, timeToDaysAndTimeOfDay
, daysAndTimeOfDayToTime
, utcToLocalTimeOfDay
, localToUTCTimeOfDay
, timeToTimeOfDay
, pastMidnight
, timeOfDayToTime
, sinceMidnight
, dayFractionToTimeOfDay
, timeOfDayToDayFraction
) where
import Control.DeepSeq
import Data.Data
import Data.Fixed
import Data.Time.Calendar.Private
import Data.Time.Clock.Internal.DiffTime
import Data.Time.Clock.Internal.NominalDiffTime
import Data.Time.LocalTime.Internal.TimeZone
data TimeOfDay = TimeOfDay
{ todHour :: Int
, todMin :: Int
, todSec :: Pico
} deriving (Eq, Ord, Data, Typeable)
instance NFData TimeOfDay where
rnf (TimeOfDay h m s) = rnf h `seq` rnf m `seq` rnf s `seq` ()
midnight :: TimeOfDay
midnight = TimeOfDay 0 0 0
midday :: TimeOfDay
midday = TimeOfDay 12 0 0
instance Show TimeOfDay where
show (TimeOfDay h m s) = (show2 h) ++ ":" ++ (show2 m) ++ ":" ++ (show2Fixed s)
makeTimeOfDayValid :: Int -> Int -> Pico -> Maybe TimeOfDay
makeTimeOfDayValid h m s = do
_ <- clipValid 0 23 h
_ <- clipValid 0 59 m
_ <- clipValid 0 60.999999999999 s
return (TimeOfDay h m s)
timeToDaysAndTimeOfDay :: NominalDiffTime -> (Integer, TimeOfDay)
timeToDaysAndTimeOfDay dt = let
s = realToFrac dt
(m, ms) = divMod' s 60
(h, hm) = divMod' m 60
(d, dh) = divMod' h 24
in (d, TimeOfDay dh hm ms)
daysAndTimeOfDayToTime :: Integer -> TimeOfDay -> NominalDiffTime
daysAndTimeOfDayToTime d (TimeOfDay dh hm ms) =
(+) (realToFrac ms) $ (*) 60 $ (+) (realToFrac hm) $ (*) 60 $ (+) (realToFrac dh) $ (*) 24 $ realToFrac d
utcToLocalTimeOfDay :: TimeZone -> TimeOfDay -> (Integer, TimeOfDay)
utcToLocalTimeOfDay zone (TimeOfDay h m s) = (fromIntegral (div h' 24), TimeOfDay (mod h' 24) (mod m' 60) s)
where
m' = m + timeZoneMinutes zone
h' = h + (div m' 60)
localToUTCTimeOfDay :: TimeZone -> TimeOfDay -> (Integer, TimeOfDay)
localToUTCTimeOfDay zone = utcToLocalTimeOfDay (minutesToTimeZone (negate (timeZoneMinutes zone)))
posixDayLength :: DiffTime
posixDayLength = fromInteger 86400
timeToTimeOfDay :: DiffTime -> TimeOfDay
timeToTimeOfDay dt
| dt >= posixDayLength = TimeOfDay 23 59 (60 + (realToFrac (dt posixDayLength)))
timeToTimeOfDay dt = TimeOfDay (fromInteger h) (fromInteger m) s
where
s' = realToFrac dt
s = mod' s' 60
m' = div' s' 60
m = mod' m' 60
h = div' m' 60
pastMidnight :: DiffTime -> TimeOfDay
pastMidnight = timeToTimeOfDay
timeOfDayToTime :: TimeOfDay -> DiffTime
timeOfDayToTime (TimeOfDay h m s) = ((fromIntegral h) * 60 + (fromIntegral m)) * 60 + (realToFrac s)
sinceMidnight :: TimeOfDay -> DiffTime
sinceMidnight = timeOfDayToTime
dayFractionToTimeOfDay :: Rational -> TimeOfDay
dayFractionToTimeOfDay df = timeToTimeOfDay (realToFrac (df * 86400))
timeOfDayToDayFraction :: TimeOfDay -> Rational
timeOfDayToDayFraction tod = realToFrac (timeOfDayToTime tod) / realToFrac posixDayLength