{-# LANGUAGE CPP #-}
module Data.Avro.Internal.Time where

-- Utility functions to work with times

import Data.Fixed            (Fixed (..))
import Data.Maybe            (fromJust)
import Data.Time
import Data.Time.Clock
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
#if MIN_VERSION_time(1,9,0)
import Data.Time.Format.Internal
#else
import Data.Time.Format
#endif

epoch :: UTCTime
epoch :: UTCTime
epoch = POSIXTime -> UTCTime
posixSecondsToUTCTime POSIXTime
0
{-# INLINE epoch #-}

epochDate :: Day
epochDate :: Day
epochDate = Maybe Day -> Day
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Day -> Day) -> Maybe Day -> Day
forall a b. (a -> b) -> a -> b
$ TimeLocale -> [(Char, String)] -> Maybe Day
forall t. ParseTime t => TimeLocale -> [(Char, String)] -> Maybe t
buildTime TimeLocale
defaultTimeLocale []

daysSinceEpoch :: Day -> Integer
daysSinceEpoch :: Day -> Integer
daysSinceEpoch Day
d = Day -> Day -> Integer
diffDays Day
d Day
epochDate

fromDaysSinceEpoch :: Integer -> Day
fromDaysSinceEpoch :: Integer -> Day
fromDaysSinceEpoch Integer
n = Integer -> Day -> Day
addDays Integer
n Day
epochDate

diffTimeToMicros :: DiffTime -> Integer
diffTimeToMicros :: DiffTime -> Integer
diffTimeToMicros = (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
1000000) (Integer -> Integer)
-> (DiffTime -> Integer) -> DiffTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiffTime -> Integer
diffTimeToPicoseconds

microsToDiffTime :: Integer -> DiffTime
microsToDiffTime :: Integer -> DiffTime
microsToDiffTime = Integer -> DiffTime
picosecondsToDiffTime (Integer -> DiffTime)
-> (Integer -> Integer) -> Integer -> DiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000)

diffTimeToMillis :: DiffTime -> Integer
diffTimeToMillis :: DiffTime -> Integer
diffTimeToMillis = (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
1000000000) (Integer -> Integer)
-> (DiffTime -> Integer) -> DiffTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiffTime -> Integer
diffTimeToPicoseconds

millisToDiffTime :: Integer -> DiffTime
millisToDiffTime :: Integer -> DiffTime
millisToDiffTime = Integer -> DiffTime
picosecondsToDiffTime (Integer -> DiffTime)
-> (Integer -> Integer) -> Integer -> DiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000000)

utcTimeToMicros :: UTCTime -> Integer
utcTimeToMicros :: UTCTime -> Integer
utcTimeToMicros UTCTime
t = DiffTime -> Integer
diffTimeToPicoseconds (POSIXTime -> DiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac (UTCTime -> UTCTime -> POSIXTime
diffUTCTime UTCTime
t UTCTime
epoch)) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
1000000

utcTimeToMillis :: UTCTime -> Integer
utcTimeToMillis :: UTCTime -> Integer
utcTimeToMillis = (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
1000) (Integer -> Integer) -> (UTCTime -> Integer) -> UTCTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> Integer
utcTimeToMicros

microsToUTCTime :: Integer -> UTCTime
microsToUTCTime :: Integer -> UTCTime
microsToUTCTime Integer
x = POSIXTime -> UTCTime -> UTCTime
addUTCTime (DiffTime -> POSIXTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac (DiffTime -> POSIXTime) -> DiffTime -> POSIXTime
forall a b. (a -> b) -> a -> b
$ Integer -> DiffTime
picosecondsToDiffTime (Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000)) UTCTime
epoch

millisToUTCTime :: Integer -> UTCTime
millisToUTCTime :: Integer -> UTCTime
millisToUTCTime Integer
x = POSIXTime -> UTCTime -> UTCTime
addUTCTime (DiffTime -> POSIXTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac (DiffTime -> POSIXTime) -> DiffTime -> POSIXTime
forall a b. (a -> b) -> a -> b
$ Integer -> DiffTime
picosecondsToDiffTime (Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000000)) UTCTime
epoch