packages feed

cleveland-0.1.2: src/Hedgehog/Range/Tezos/Core/Timestamp.hs

-- SPDX-FileCopyrightText: 2022 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | Timestamp range utility functions
module Hedgehog.Range.Tezos.Core.Timestamp
  ( minTimestamp
  , maxTimestamp
  , midTimestamp
  , timestampRangeFromSeconds
  ) where

import Data.Time.Calendar (Day, addDays, diffDays)
import Data.Time.Clock (UTCTime(..))
import Data.Time.Format (defaultTimeLocale, parseTimeM)
import Hedgehog.Range (Range)
import Hedgehog.Range qualified as Range

import Morley.Tezos.Core (Timestamp, timestampFromSeconds, timestampFromUTCTime)

-- | Generate a linear 'Range' of timestamps between lower and upper bounds specified in seconds
-- from the start of the UNIX epoch (Jan 1st 1970).
timestampRangeFromSeconds :: Integer -> Integer -> Range Timestamp
timestampRangeFromSeconds l h = timestampFromSeconds <$> Range.linear l h

-- | Minimal (earliest) timestamp used for the default @Range Timestamp@
minTimestamp :: Timestamp
minTimestamp = timestampFromUTCTime $ UTCTime minDay (fromIntegralToRealFrac minSec)

-- | Maximal (latest) timestamp used for the default @Range Timestamp@
maxTimestamp :: Timestamp
maxTimestamp = timestampFromUTCTime $ UTCTime maxDay (fromIntegralToRealFrac maxSec)

-- | Median of 'minTimestamp' and 'maxTimestamp'.
-- Useful for testing (exactly half of generated dates will be before and after
-- this date).
midTimestamp :: Timestamp
midTimestamp = timestampFromUTCTime $
  UTCTime ( ((maxDay `diffDays` minDay) `div` 2) `addDays` minDay)
          (fromIntegralToRealFrac $ (maxSec - minSec) `div` 2)

minDay :: Day
minDay = fromMaybe (error "failed to parse day 2008-11-01") $
            parseTimeM True defaultTimeLocale "%Y-%-m-%-d" "2008-11-01"

maxDay :: Day
maxDay = fromMaybe (error "failed to parse day 2024-11-01") $
            parseTimeM True defaultTimeLocale "%Y-%-m-%-d" "2024-11-01"

minSec :: Integer
minSec = 0

maxSec :: Integer
maxSec = 86399