{-# 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
{ LocalTime t -> t
localTimeUnwrap :: t
, LocalTime t -> TimezoneOffset
localTimeGetTimezone :: TimezoneOffset
}
instance Show t => Show (LocalTime t) where
show :: LocalTime t -> String
show (LocalTime t
t TimezoneOffset
tz) = t -> String
forall a. Show a => a -> String
show t
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ TimezoneOffset -> String
forall a. Show a => a -> String
show TimezoneOffset
tz
instance Eq t => Eq (LocalTime t) where
LocalTime t
t1 TimezoneOffset
tz1 == :: LocalTime t -> LocalTime t -> Bool
== LocalTime t
t2 TimezoneOffset
tz2 = TimezoneOffset
tz1 TimezoneOffset -> TimezoneOffset -> Bool
forall a. Eq a => a -> a -> Bool
== TimezoneOffset
tz2 Bool -> Bool -> Bool
&& t
t1 t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
t2
instance (Ord t, Time t) => Ord (LocalTime t) where
compare :: LocalTime t -> LocalTime t -> Ordering
compare l1 :: LocalTime t
l1@(LocalTime t
g1 TimezoneOffset
tz1) l2 :: LocalTime t
l2@(LocalTime t
g2 TimezoneOffset
tz2) =
case TimezoneOffset -> TimezoneOffset -> Ordering
forall a. Ord a => a -> a -> Ordering
compare TimezoneOffset
tz1 TimezoneOffset
tz2 of
Ordering
EQ -> t -> t -> Ordering
forall a. Ord a => a -> a -> Ordering
compare t
g1 t
g2
Ordering
_ -> let t1 :: t
t1 = LocalTime t -> t
forall t. Time t => LocalTime t -> t
localTimeToGlobal LocalTime t
l1
t2 :: t
t2 = LocalTime t -> t
forall t. Time t => LocalTime t -> t
localTimeToGlobal LocalTime t
l2
in t -> t -> Ordering
forall a. Ord a => a -> a -> Ordering
compare t
t1 t
t2
instance Functor LocalTime where
fmap :: (a -> b) -> LocalTime a -> LocalTime b
fmap a -> b
f (LocalTime a
t TimezoneOffset
tz) = b -> TimezoneOffset -> LocalTime b
forall t. t -> TimezoneOffset -> LocalTime t
LocalTime (a -> b
f a
t) TimezoneOffset
tz
localTime :: Time t => TimezoneOffset -> t -> LocalTime t
localTime :: TimezoneOffset -> t -> LocalTime t
localTime TimezoneOffset
tz t
t = t -> TimezoneOffset -> LocalTime t
forall t. t -> TimezoneOffset -> LocalTime t
LocalTime t
t TimezoneOffset
tz
localTimeToGlobal :: Time t => LocalTime t -> t
localTimeToGlobal :: LocalTime t -> t
localTimeToGlobal (LocalTime t
local TimezoneOffset
tz)
| TimezoneOffset
tz TimezoneOffset -> TimezoneOffset -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> TimezoneOffset
TimezoneOffset Int
0 = t
local
| Bool
otherwise = ElapsedP -> t
forall t1 t2. (Timeable t1, Time t2) => t1 -> t2
timeConvert (ElapsedP -> t) -> ElapsedP -> t
forall a b. (a -> b) -> a -> b
$ ElapsedP -> Seconds -> ElapsedP
elapsedTimeAddSecondsP (t -> ElapsedP
forall t. Timeable t => t -> ElapsedP
timeGetElapsedP t
local) Seconds
tzSecs
where tzSecs :: Seconds
tzSecs = Seconds -> Seconds
forall a. Num a => a -> a
negate (Seconds -> Seconds) -> Seconds -> Seconds
forall a b. (a -> b) -> a -> b
$ TimezoneOffset -> Seconds
timezoneOffsetToSeconds TimezoneOffset
tz
localTimeFromGlobal :: Time t => t -> LocalTime t
localTimeFromGlobal :: t -> LocalTime t
localTimeFromGlobal = TimezoneOffset -> t -> LocalTime t
forall t. Time t => TimezoneOffset -> t -> LocalTime t
localTime (Int -> TimezoneOffset
TimezoneOffset Int
0)
localTimeSetTimezone :: Time t => TimezoneOffset -> LocalTime t -> LocalTime t
localTimeSetTimezone :: TimezoneOffset -> LocalTime t -> LocalTime t
localTimeSetTimezone TimezoneOffset
tz currentLocal :: LocalTime t
currentLocal@(LocalTime t
t TimezoneOffset
currentTz)
| Seconds
diffTz Seconds -> Seconds -> Bool
forall a. Eq a => a -> a -> Bool
== Seconds
0 = LocalTime t
currentLocal
| Bool
otherwise = t -> TimezoneOffset -> LocalTime t
forall t. t -> TimezoneOffset -> LocalTime t
LocalTime (ElapsedP -> t
forall t1 t2. (Timeable t1, Time t2) => t1 -> t2
timeConvert ElapsedP
t') TimezoneOffset
tz
where t' :: ElapsedP
t' = ElapsedP -> Seconds -> ElapsedP
elapsedTimeAddSecondsP (t -> ElapsedP
forall t. Timeable t => t -> ElapsedP
timeGetElapsedP t
t) Seconds
diffTz
diffTz :: Seconds
diffTz = TimezoneOffset -> Seconds
timezoneOffsetToSeconds TimezoneOffset
tz Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
- TimezoneOffset -> Seconds
timezoneOffsetToSeconds TimezoneOffset
currentTz
localTimeConvert :: (Time t1, Time t2) => LocalTime t1 -> LocalTime t2
localTimeConvert :: LocalTime t1 -> LocalTime t2
localTimeConvert = (t1 -> t2) -> LocalTime t1 -> LocalTime t2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap t1 -> t2
forall t1 t2. (Timeable t1, Time t2) => t1 -> t2
timeConvert