content: -- | @since 0.2.0
  module Faker.DateTime where
  
  import Control.Monad.IO.Class (liftIO)
  import Data.Text
  import Data.Time
  import Faker
  import Faker.Combinators
  
  -- | Fake 'UTCTime' between 17-11-1858 and the current time. Note that
  -- this function is not deterministic as the current time is not
  -- constant. If you want deterministic output, use 'utcBetween'.
  utc :: Fake UTCTime
  utc = do
    now <- liftIO getCurrentTime
    utcBetween
      (UTCTime
         { utctDay = (ModifiedJulianDay {toModifiedJulianDay = 0})
         , utctDayTime = 0
         })
      now
  
  -- | Fake 'Day' between 17-11-1858 and the current day. Note that
  -- this function is not deterministic as the current time is not
  -- constant. If you want deterministic output, use 'dayBetween'.
  day :: Fake Day
  day = do
    now <- liftIO getCurrentTime
    dayBetween (ModifiedJulianDay {toModifiedJulianDay = 0}) (utctDay now)
  
  -- | Generates a random UTCTime in the range [from, to].
  utcBetween :: UTCTime -> UTCTime -> Fake UTCTime
  utcBetween from to = do
    delta <- fromRange (0 :: Double, realToFrac $ diffUTCTime to from)
    return $ addUTCTime (realToFrac delta) from
  
  -- | Generates a random Day in the range [from, to].
  dayBetween :: Day -> Day -> Fake Day
  dayBetween from to = do
    delta <- fromRange (0, diffDays to from)
    return $ addDays delta from
  
  -- | Generates a random Day in the year range [from, to].
  dayBetweenYears :: Integer -> Integer -> Fake Day
  dayBetweenYears ystart yend =
    fakeEnumFromTo (fromGregorian ystart 1 1) (fromGregorian yend 12 31)
  
  -- | Generates a random 'DiffTime' between hour range [from, to].
  timeBetweenHours :: Int -> Int -> Fake DiffTime
  timeBetweenHours hstart hend =
    secondsToDiffTime <$> fromRange (fromIntegral from, fromIntegral to)
    where
      from = hstart * 3600
      to = hend * 3599
  
  -- | Generate a random 'UTCTime' between year range [from, to].
  utcBetweenYears :: Integer -> Integer -> Fake UTCTime
  utcBetweenYears ystart yend =
    UTCTime <$> dayBetweenYears ystart yend <*> timeBetweenHours 0 24
  