module PostgreSQL.Binary.Interval where
import PostgreSQL.Binary.Prelude hiding (months)
import qualified PostgreSQL.Binary.Time as Time
data Interval = Interval
{ Interval -> Int64
micros :: Int64,
Interval -> Int32
days :: Int32,
Interval -> Int32
months :: Int32
}
deriving (Int -> Interval -> ShowS
[Interval] -> ShowS
Interval -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Interval] -> ShowS
$cshowList :: [Interval] -> ShowS
show :: Interval -> String
$cshow :: Interval -> String
showsPrec :: Int -> Interval -> ShowS
$cshowsPrec :: Int -> Interval -> ShowS
Show, Interval -> Interval -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Interval -> Interval -> Bool
$c/= :: Interval -> Interval -> Bool
== :: Interval -> Interval -> Bool
$c== :: Interval -> Interval -> Bool
Eq)
DiffTime
maxDiffTime :: DiffTime = DiffTime
1780000 forall a. Num a => a -> a -> a
* Int64 -> DiffTime
Time.microsToDiffTime Int64
Time.yearMicros
DiffTime
minDiffTime :: DiffTime = forall a. Num a => a -> a
negate DiffTime
maxDiffTime
fromDiffTime :: DiffTime -> Maybe Interval
fromDiffTime :: DiffTime -> Maybe Interval
fromDiffTime DiffTime
x =
if DiffTime
x forall a. Ord a => a -> a -> Bool
> DiffTime
maxDiffTime Bool -> Bool -> Bool
|| DiffTime
x forall a. Ord a => a -> a -> Bool
< DiffTime
minDiffTime
then forall a. Maybe a
Nothing
else forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Integer -> Interval
fromPicosUnsafe (forall a b. a -> b
unsafeCoerce DiffTime
x)
fromPicosUnsafe :: Integer -> Interval
fromPicosUnsafe :: Integer -> Interval
fromPicosUnsafe =
forall s a. State s a -> s -> a
evalState forall a b. (a -> b) -> a -> b
$ do
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Integral a => a -> a -> a
div (Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
6)
Integer
u <- forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
state forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> (b, a)
swap forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Integral a => a -> a -> (a, a)
divMod (Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
6 forall a. Num a => a -> a -> a
* Integer
60 forall a. Num a => a -> a -> a
* Integer
60 forall a. Num a => a -> a -> a
* Integer
24)
Integer
d <- forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
state forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> (b, a)
swap forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Integral a => a -> a -> (a, a)
divMod (Integer
31)
Integer
m <- forall (m :: * -> *) s. Monad m => StateT s m s
get
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int64 -> Int32 -> Int32 -> Interval
Interval (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
u) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
d) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
m)
toDiffTime :: Interval -> DiffTime
toDiffTime :: Interval -> DiffTime
toDiffTime Interval
x =
Integer -> DiffTime
picosecondsToDiffTime forall a b. (a -> b) -> a -> b
$
(Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
6)
forall a. Num a => a -> a -> a
* ( forall a b. (Integral a, Num b) => a -> b
fromIntegral (Interval -> Int64
micros Interval
x)
forall a. Num a => a -> a -> a
+ Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
6 forall a. Num a => a -> a -> a
* Integer
60 forall a. Num a => a -> a -> a
* Integer
60 forall a. Num a => a -> a -> a
* Integer
24 forall a. Num a => a -> a -> a
* (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Interval -> Int32
days Interval
x forall a. Num a => a -> a -> a
+ Int32
31 forall a. Num a => a -> a -> a
* Interval -> Int32
months Interval
x))
)