{-# LANGUAGE FlexibleInstances #-}
module Data.Hourglass.Local
(
LocalTime
, localTime
, localTimeUnwrap
, localTimeToGlobal
, localTimeFromGlobal
, localTimeGetTimezone
, 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
localTime :: Time t => TimezoneOffset -> t -> LocalTime t
localTime tz t = LocalTime t tz
localTimeToGlobal :: Time t => LocalTime t -> t
localTimeToGlobal (LocalTime local tz)
| tz == TimezoneOffset 0 = local
| otherwise = timeConvert $ elapsedTimeAddSecondsP (timeGetElapsedP local) tzSecs
where tzSecs = negate $ timezoneOffsetToSeconds tz
localTimeFromGlobal :: Time t => t -> LocalTime t
localTimeFromGlobal = localTime (TimezoneOffset 0)
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