module Fake.Provider.DateTime where

------------------------------------------------------------------------------
import Data.Time
------------------------------------------------------------------------------
import Fake.Combinators
import Fake.Types
------------------------------------------------------------------------------

------------------------------------------------------------------------------
-- | Generates a random UTCTime in the range [from, to].
utcBetween :: UTCTime -> UTCTime -> FGen UTCTime
utcBetween :: UTCTime -> UTCTime -> FGen UTCTime
utcBetween UTCTime
from UTCTime
to = do
    Double
delta <- (Double, Double) -> FGen Double
forall a. Random a => (a, a) -> FGen a
fromRange (Double
0 :: Double, NominalDiffTime -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac (NominalDiffTime -> Double) -> NominalDiffTime -> Double
forall a b. (a -> b) -> a -> b
$ UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime UTCTime
to UTCTime
from)
    UTCTime -> FGen UTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (UTCTime -> FGen UTCTime) -> UTCTime -> FGen UTCTime
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> UTCTime -> UTCTime
addUTCTime (Double -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
delta) UTCTime
from

------------------------------------------------------------------------------
-- | Generates a random Day in the range [from, to].
dayBetween :: Day -> Day -> FGen Day
dayBetween :: Day -> Day -> FGen Day
dayBetween Day
from Day
to = do
    Integer
delta <- (Integer, Integer) -> FGen Integer
forall a. Random a => (a, a) -> FGen a
fromRange (Integer
0, Day -> Day -> Integer
diffDays Day
to Day
from)
    Day -> FGen Day
forall (m :: * -> *) a. Monad m => a -> m a
return (Day -> FGen Day) -> Day -> FGen Day
forall a b. (a -> b) -> a -> b
$ Integer -> Day -> Day
addDays Integer
delta Day
from

dayBetweenYears :: Integer -> Integer -> FGen Day
dayBetweenYears :: Integer -> Integer -> FGen Day
dayBetweenYears Integer
ystart Integer
yend =
    Day -> Day -> FGen Day
forall a. Enum a => a -> a -> FGen a
fakeEnumFromTo (Integer -> Int -> Int -> Day
fromGregorian Integer
ystart Int
1 Int
1) (Integer -> Int -> Int -> Day
fromGregorian Integer
yend Int
12 Int
31)

timeBetweenHours :: Int -> Int -> FGen DiffTime
timeBetweenHours :: Int -> Int -> FGen DiffTime
timeBetweenHours Int
hstart Int
hend = Integer -> DiffTime
secondsToDiffTime (Integer -> DiffTime) -> FGen Integer -> FGen DiffTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer, Integer) -> FGen Integer
forall a. Random a => (a, a) -> FGen a
fromRange (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
from, Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
to)
  where
    from :: Int
from = Int
hstart Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3600
    to :: Int
to = Int
hend Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3599

utcBetweenYears :: Integer -> Integer -> FGen UTCTime
utcBetweenYears :: Integer -> Integer -> FGen UTCTime
utcBetweenYears Integer
ystart Integer
yend = Day -> DiffTime -> UTCTime
UTCTime (Day -> DiffTime -> UTCTime)
-> FGen Day -> FGen (DiffTime -> UTCTime)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> Integer -> FGen Day
dayBetweenYears Integer
ystart Integer
yend FGen (DiffTime -> UTCTime) -> FGen DiffTime -> FGen UTCTime
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Int -> FGen DiffTime
timeBetweenHours Int
0 Int
24