module Data.Hourglass.Local
(
LocalTime(..)
, localTime
, localTimeToGlobal
, localTimeSetTimezone
, localTimeConvert
) where
import Data.Hourglass.Types
import Data.Hourglass.Time
import Data.Hourglass.Diff
data LocalTime t = LocalTime
{ localTimeUnwrap :: t
, localTimeGetTimezone :: TimezoneOffset
}
instance Show t => Show (LocalTime t) where
show (LocalTime t tz) = show t ++ show tz
instance Eq t => Eq (LocalTime t) where
LocalTime t1 tz1 == LocalTime t2 tz2 = tz1 == tz2 && t1 == t2
instance (Ord t, Time t) => Ord (LocalTime t) where
compare l1@(LocalTime g1 tz1) l2@(LocalTime g2 tz2) =
case compare tz1 tz2 of
EQ -> compare g1 g2
_ -> let t1 = localTimeToGlobal l1
t2 = localTimeToGlobal l2
in compare t1 t2
instance Functor LocalTime where
fmap f (LocalTime t tz) = LocalTime (f t) tz
instance Time t => Timeable (LocalTime t) where
timeGetElapsedP (LocalTime t _) = timeGetElapsedP t
timeGetElapsed (LocalTime t _) = timeGetElapsed t
timeGetTimezone (LocalTime _ tz) = Just tz
timeGetNanoSeconds (LocalTime t _) = timeGetNanoSeconds t
localTime :: Time t => TimezoneOffset -> t -> LocalTime t
localTime tz t = LocalTime (timeConvert t') tz
where currentTz = maybe (TimezoneOffset 0) id $ timeGetTimezone t
t' = elapsedTimeAddSecondsP (timeGetElapsedP t) diffTz
diffTz = timezoneOffsetToSeconds tz timezoneOffsetToSeconds currentTz
localTimeToGlobal :: Time t => LocalTime t -> t
localTimeToGlobal (LocalTime local tz) = timeConvert $ elapsedTimeAddSecondsP (timeGetElapsedP local) tzSecs
where tzSecs = negate $ timezoneOffsetToSeconds tz
localTimeSetTimezone :: Time t => TimezoneOffset -> LocalTime t -> LocalTime t
localTimeSetTimezone tz currentLocal@(LocalTime t currentTz)
| diffTz == 0 = currentLocal
| otherwise = LocalTime (timeConvert t') tz
where t' = elapsedTimeAddSecondsP (timeGetElapsedP t) diffTz
diffTz = timezoneOffsetToSeconds tz timezoneOffsetToSeconds currentTz
localTimeConvert :: (Time t1, Time t2) => LocalTime t1 -> LocalTime t2
localTimeConvert = fmap timeConvert