module Data.Time.Exts.Unix (
Unix(..)
, UnixDate(..)
, UnixTime(..)
, UnixTimeMillis(..)
, UnixTimeMicros(..)
, UnixTimeNanos(..)
, UnixTimePicos(..)
, UnixDateTime(..)
, UnixDateTimeMillis(..)
, UnixDateTimeMicros(..)
, UnixDateTimeNanos(..)
, UnixDateTimePicos(..)
, createUnixDate
, createUnixTime
, createUnixTimeMillis
, createUnixTimeMicros
, createUnixTimeNanos
, createUnixTimePicos
, createUnixDateTime
, createUnixDateTimeMillis
, createUnixDateTimeMicros
, createUnixDateTimeNanos
, createUnixDateTimePicos
, getCurrentUnixDate
, getCurrentUnixTime
, getCurrentUnixTimeMillis
, getCurrentUnixTimeMicros
, getCurrentUnixTimeNanos
, getCurrentUnixTimePicos
, getCurrentUnixDateTime
, getCurrentUnixDateTimeMillis
, getCurrentUnixDateTimeMicros
, getCurrentUnixDateTimeNanos
, getCurrentUnixDateTimePicos
, prettyUnixDate
, prettyUnixTime
, prettyUnixDateTime
) where
import Control.Arrow ((***), first)
import Control.DeepSeq (NFData)
import Data.Aeson (FromJSON, ToJSON)
import Data.Convertible (Convertible(..), convert)
import Data.Int (Int16, Int32, Int64)
import Data.Label (get, mkLabels, modify)
import Data.Time.Exts.Base
import Data.Time.Exts.C
import Data.Typeable (Typeable)
import Foreign.C.Types (CLong(..))
import Foreign.Marshal.Utils (with)
import Foreign.Ptr (castPtr, nullPtr, plusPtr)
import Foreign.Storable (Storable(..))
import GHC.Generics (Generic)
import System.Random (Random(..))
import Text.Printf (printf)
class Unix u where
unixBase :: u -> Int64
unixNorm :: u -> Int64
newtype UnixDate = UnixDate {
_ud_day_base :: Int32
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixTime = UnixTime {
_ut_sec_base :: Int32
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixTimeMillis = UnixTimeMillis {
_ut_mil_base :: Int32
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixTimeMicros = UnixTimeMicros {
_ut_mic_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixTimeNanos = UnixTimeNanos {
_ut_nan_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixTimePicos = UnixTimePicos {
_ut_pic_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixDateTime = UnixDateTime {
_udt_sec_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixDateTimeMillis = UnixDateTimeMillis {
_udt_mil_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
newtype UnixDateTimeMicros = UnixDateTimeMicros {
_udt_mic_base :: Int64
} deriving (Eq,FromJSON,Generic,NFData,Ord,Storable,ToJSON,Typeable)
data UnixDateTimeNanos = UnixDateTimeNanos {
_udt_nan_base :: !Int64
, _udt_nan_nano :: !Int16
} deriving (Eq,Generic,Ord,Typeable)
data UnixDateTimePicos = UnixDateTimePicos {
_udt_pic_base :: !Int64
, _udt_pic_pico :: !Int32
} deriving (Eq,Generic,Ord,Typeable)
instance FromJSON UnixDateTimeNanos
instance FromJSON UnixDateTimePicos
instance NFData UnixDateTimeNanos
instance NFData UnixDateTimePicos
instance Storable UnixDateTimeNanos where
sizeOf _ = 10
alignment = sizeOf
peekElemOff ptr n = do
let off = 10 * n
base <- peek . plusPtr ptr $ off
nano <- peek . plusPtr ptr $ off + 8
return $! UnixDateTimeNanos base nano
pokeElemOff ptr n UnixDateTimeNanos{..} = do
let off = 10 * n
poke (plusPtr ptr $ off ) _udt_nan_base
poke (plusPtr ptr $ off + 8) _udt_nan_nano
instance Storable UnixDateTimePicos where
sizeOf _ = 12
alignment = sizeOf
peekElemOff ptr n = do
let off = 12 * n
base <- peek . plusPtr ptr $ off
pico <- peek . plusPtr ptr $ off + 8
return $! UnixDateTimePicos base pico
pokeElemOff ptr n UnixDateTimePicos{..} = do
let off = 12 * n
poke (plusPtr ptr $ off ) _udt_pic_base
poke (plusPtr ptr $ off + 8) _udt_pic_pico
instance ToJSON UnixDateTimeNanos
instance ToJSON UnixDateTimePicos
mkLabels [ ''DateTimeStruct
, ''UnixDate
, ''UnixTime
, ''UnixTimeMillis
, ''UnixTimeMicros
, ''UnixTimeNanos
, ''UnixTimePicos
, ''UnixDateTime
, ''UnixDateTimeMillis
, ''UnixDateTimeMicros
, ''UnixDateTimeNanos
, ''UnixDateTimePicos
]
instance Bounded UnixDate where
minBound = UnixDate 0
maxBound = UnixDate 2932896
instance Bounded UnixTime where
minBound = UnixTime 0
maxBound = UnixTime 86399
instance Bounded UnixTimeMillis where
minBound = UnixTimeMillis 0
maxBound = UnixTimeMillis 86399999
instance Bounded UnixTimeMicros where
minBound = UnixTimeMicros 0
maxBound = UnixTimeMicros 86399999999
instance Bounded UnixTimeNanos where
minBound = UnixTimeNanos 0
maxBound = UnixTimeNanos 86399999999999
instance Bounded UnixTimePicos where
minBound = UnixTimePicos 0
maxBound = UnixTimePicos 86399999999999999
instance Bounded UnixDateTime where
minBound = UnixDateTime 0
maxBound = UnixDateTime 253402300799
instance Bounded UnixDateTimeMillis where
minBound = UnixDateTimeMillis 0
maxBound = UnixDateTimeMillis 253402300799999
instance Bounded UnixDateTimeMicros where
minBound = UnixDateTimeMicros 0
maxBound = UnixDateTimeMicros 253402300799999999
instance Bounded UnixDateTimeNanos where
minBound = UnixDateTimeNanos 0 0
maxBound = UnixDateTimeNanos 253402300799999999 999
instance Bounded UnixDateTimePicos where
minBound = UnixDateTimePicos 0 0
maxBound = UnixDateTimePicos 253402300799999999 999999
instance Unix UnixDate where
unixBase = fromIntegral . get ud_day_base
unixNorm = unixBase
instance Unix UnixTime where
unixBase = fromIntegral . get ut_sec_base
unixNorm = unixBase
instance Unix UnixTimeMillis where
unixBase = fromIntegral . get ut_mil_base
unixNorm = flip div 1000 . unixBase
instance Unix UnixTimeMicros where
unixBase = get ut_mic_base
unixNorm = flip div 1000000 . unixBase
instance Unix UnixTimeNanos where
unixBase = get ut_nan_base
unixNorm = flip div 1000000000 . unixBase
instance Unix UnixTimePicos where
unixBase = get ut_pic_base
unixNorm = flip div 1000000000000 . unixBase
instance Unix UnixDateTime where
unixBase = get udt_sec_base
unixNorm = unixBase
instance Unix UnixDateTimeMillis where
unixBase = get udt_mil_base
unixNorm = flip div 1000 . unixBase
instance Unix UnixDateTimeMicros where
unixBase = get udt_mic_base
unixNorm = flip div 1000000 . unixBase
instance Unix UnixDateTimeNanos where
unixBase = get udt_nan_base
unixNorm = flip div 1000000 . unixBase
instance Unix UnixDateTimePicos where
unixBase = get udt_pic_base
unixNorm = flip div 1000000 . unixBase
instance DateTimeMath UnixDate Day where
date `plus` Day day =
check "plus{UnixDate,Day}" $
modify ud_day_base (+ day) date
instance DateTimeMath UnixTime Hour where
time `plus` Hour hour =
check "plus{UnixTime,Hour}" $
modify ut_sec_base (+ fromIntegral hour * 3600) time
instance DateTimeMath UnixTime Minute where
time `plus` Minute minute =
check "plus{UnixTime,Minute}" $
modify ut_sec_base (+ fromIntegral minute * 60) time
instance DateTimeMath UnixTime Second where
time `plus` Second second =
check "plus{UnixTime,Second}" $
modify ut_sec_base (+ fromIntegral second) time
instance DateTimeMath UnixTimeMillis Hour where
time `plus` Hour hour =
check "plus{UnixTimeMillis,Hour}" $
modify ut_mil_base (+ fromIntegral hour * 3600000) time
instance DateTimeMath UnixTimeMillis Minute where
time `plus` Minute minute =
check "plus{UnixTimeMillis,Minute}" $
modify ut_mil_base (+ fromIntegral minute * 60000) time
instance DateTimeMath UnixTimeMillis Second where
time `plus` Second second =
check "plus{UnixTimeMillis,Second}" $
modify ut_mil_base (+ fromIntegral second * 1000) time
instance DateTimeMath UnixTimeMillis Millis where
time `plus` Millis millis =
check "plus{UnixTimeMillis,Millis}" $
modify ut_mil_base (+ fromIntegral millis) time
instance DateTimeMath UnixTimeMicros Hour where
time `plus` Hour hour =
check "plus{UnixTimeMicros,Hour}" $
modify ut_mic_base (+ hour * 3600000000) time
instance DateTimeMath UnixTimeMicros Minute where
time `plus` Minute minute =
check "plus{UnixTimeMicros,Minute}" $
modify ut_mic_base (+ minute * 60000000) time
instance DateTimeMath UnixTimeMicros Second where
time `plus` Second second =
check "plus{UnixTimeMicros,Second}" $
modify ut_mic_base (+ second * 1000000) time
instance DateTimeMath UnixTimeMicros Millis where
time `plus` Millis millis =
check "plus{UnixTimeMicros,Millis}" $
modify ut_mic_base (+ millis * 1000) time
instance DateTimeMath UnixTimeMicros Micros where
time `plus` Micros micros =
check "plus{UnixTimeMicros,Micros}" $
modify ut_mic_base (+ micros) time
instance DateTimeMath UnixTimeNanos Hour where
time `plus` Hour hour =
check "plus{UnixTimeNanos,Hour}" $
modify ut_nan_base (+ hour * 3600000000000) time
instance DateTimeMath UnixTimeNanos Minute where
time `plus` Minute minute =
check "plus{UnixTimeNanos,Minute}" $
modify ut_nan_base (+ minute * 60000000000) time
instance DateTimeMath UnixTimeNanos Second where
time `plus` Second second =
check "plus{UnixTimeNanos,Second}" $
modify ut_nan_base (+ second * 1000000000) time
instance DateTimeMath UnixTimeNanos Millis where
time `plus` Millis millis =
check "plus{UnixTimeNanos,Millis}" $
modify ut_nan_base (+ millis * 1000000) time
instance DateTimeMath UnixTimeNanos Micros where
time `plus` Micros micros =
check "plus{UnixTimeNanos,Micros}" $
modify ut_nan_base (+ micros * 1000) time
instance DateTimeMath UnixTimeNanos Nanos where
time `plus` Nanos nanos =
check "plus{UnixTimeNanos,Nanos}" $
modify ut_nan_base (+ nanos) time
instance DateTimeMath UnixTimePicos Hour where
time `plus` Hour hour =
check "plus{UnixTimePicos,Hour}" $
modify ut_pic_base (+ hour * 3600000000000000) time
instance DateTimeMath UnixTimePicos Minute where
time `plus` Minute minute =
check "plus{UnixTimePicos,Minute}" $
modify ut_pic_base (+ minute * 60000000000000) time
instance DateTimeMath UnixTimePicos Second where
time `plus` Second second =
check "plus{UnixTimePicos,Second}" $
modify ut_pic_base (+ second * 1000000000000) time
instance DateTimeMath UnixTimePicos Millis where
time `plus` Millis millis =
check "plus{UnixTimePicos,Millis}" $
modify ut_pic_base (+ millis * 1000000000) time
instance DateTimeMath UnixTimePicos Micros where
time `plus` Micros micros =
check "plus{UnixTimePicos,Micros}" $
modify ut_pic_base (+ micros * 1000000) time
instance DateTimeMath UnixTimePicos Nanos where
time `plus` Nanos nanos =
check "plus{UnixTimePicos,Nanos}" $
modify ut_pic_base (+ nanos * 1000) time
instance DateTimeMath UnixTimePicos Picos where
time `plus` Picos picos =
check "plus{UnixTimePicos,Picos}" $
modify ut_pic_base (+ picos) time
instance DateTimeMath UnixDateTime Day where
time `plus` Day day =
check "plus{UnixDateTime,Day}" $
modify udt_sec_base (+ fromIntegral day * 86400) time
instance DateTimeMath UnixDateTime Hour where
time `plus` Hour hour =
check "plus{UnixDateTime,Hour}" $
modify udt_sec_base (+ hour * 3600) time
instance DateTimeMath UnixDateTime Minute where
time `plus` Minute minute =
check "plus{UnixDateTime,Minute}" $
modify udt_sec_base (+ minute * 60) time
instance DateTimeMath UnixDateTime Second where
time `plus` Second second =
check "plus{UnixDateTime,Second}" $
modify udt_sec_base (+ second) time
instance DateTimeMath UnixDateTimeMillis Day where
time `plus` Day day =
check "plus{UnixDateTimeMillis,Day}" $
modify udt_mil_base (+ fromIntegral day * 86400000) time
instance DateTimeMath UnixDateTimeMillis Hour where
time `plus` Hour hour =
check "plus{UnixDateTimeMillis,Hour}" $
modify udt_mil_base (+ hour * 3600000) time
instance DateTimeMath UnixDateTimeMillis Minute where
time `plus` Minute minute =
check "plus{UnixDateTimeMillis,Minute}" $
modify udt_mil_base (+ minute * 60000) time
instance DateTimeMath UnixDateTimeMillis Second where
time `plus` Second second =
check "plus{UnixDateTimeMillis,Second}" $
modify udt_mil_base (+ second * 1000) time
instance DateTimeMath UnixDateTimeMillis Millis where
time `plus` Millis millis =
check "plus{UnixDateTimeMillis,Millis}" $
modify udt_mil_base (+ millis) time
instance DateTimeMath UnixDateTimeMicros Day where
time `plus` Day day =
check "plus{UnixDateTimeMicros,Day}" $
modify udt_mic_base (+ fromIntegral day * 86400000000) time
instance DateTimeMath UnixDateTimeMicros Hour where
time `plus` Hour hour =
check "plus{UnixDateTimeMicros,Hour}" $
modify udt_mic_base (+ hour * 3600000000) time
instance DateTimeMath UnixDateTimeMicros Minute where
time `plus` Minute minute =
check "plus{UnixDateTimeMicros,Minute}" $
modify udt_mic_base (+ minute * 60000000) time
instance DateTimeMath UnixDateTimeMicros Second where
time `plus` Second second =
check "plus{UnixDateTimeMicros,Second}" $
modify udt_mic_base (+ second * 1000000) time
instance DateTimeMath UnixDateTimeMicros Millis where
time `plus` Millis millis =
check "plus{UnixDateTimeMicros,Millis}" $
modify udt_mic_base (+ millis * 1000) time
instance DateTimeMath UnixDateTimeMicros Micros where
time `plus` Micros micros =
check "plus{UnixDateTimeMicros,Micros}" $
modify udt_mic_base (+ micros) time
instance DateTimeMath UnixDateTimeNanos Day where
time `plus` Day day =
check "plus{UnixDateTimeNanos,Day}" $
modify udt_nan_base (+ fromIntegral day * 86400000000) time
instance DateTimeMath UnixDateTimeNanos Hour where
time `plus` Hour hour =
check "plus{UnixDateTimeNanos,Hour}" $
modify udt_nan_base (+ hour * 3600000000) time
instance DateTimeMath UnixDateTimeNanos Minute where
time `plus` Minute minute =
check "plus{UnixDateTimeNanos,Minute}" $
modify udt_nan_base (+ minute * 60000000) time
instance DateTimeMath UnixDateTimeNanos Second where
time `plus` Second second =
check "plus{UnixDateTimeNanos,Second}" $
modify udt_nan_base (+ second * 1000000) time
instance DateTimeMath UnixDateTimeNanos Millis where
time `plus` Millis millis =
check "plus{UnixDateTimeNanos,Millis}" $
modify udt_nan_base (+ millis * 1000) time
instance DateTimeMath UnixDateTimeNanos Micros where
time `plus` Micros micros =
check "plus{UnixDateTimeNanos,Micros}" $
modify udt_nan_base (+ micros) time
instance DateTimeMath UnixDateTimeNanos Nanos where
UnixDateTimeNanos{..} `plus` Nanos nanos =
check "plus{UnixDateTimeNanos,Nanos}" .
uncurry UnixDateTimeNanos .
((+ _udt_nan_base) *** fromIntegral) .
flip divMod 1000 $
fromIntegral _udt_nan_nano + nanos
instance DateTimeMath UnixDateTimePicos Day where
time `plus` Day day =
check "plus{UnixDateTimePicos,Day}" $
modify udt_pic_base (+ fromIntegral day * 86400000000) time
instance DateTimeMath UnixDateTimePicos Hour where
time `plus` Hour hour =
check "plus{UnixDateTimePicos,Hour}" $
modify udt_pic_base (+ hour * 3600000000) time
instance DateTimeMath UnixDateTimePicos Minute where
time `plus` Minute minute =
check "plus{UnixDateTimePicos,Minute}" $
modify udt_pic_base (+ minute * 60000000) time
instance DateTimeMath UnixDateTimePicos Second where
time `plus` Second second =
check "plus{UnixDateTimePicos,Second}" $
modify udt_pic_base (+ second * 1000000) time
instance DateTimeMath UnixDateTimePicos Millis where
time `plus` Millis millis =
check "plus{UnixDateTimePicos,Millis}" $
modify udt_pic_base (+ millis * 1000) time
instance DateTimeMath UnixDateTimePicos Micros where
time `plus` Micros micros =
check "plus{UnixDateTimePicos,Micros}" $
modify udt_pic_base (+ micros) time
instance DateTimeMath UnixDateTimePicos Nanos where
UnixDateTimePicos{..} `plus` Nanos nanos =
check "plus{UnixDateTimePicos,Nanos}" .
uncurry UnixDateTimePicos .
((+ _udt_pic_base) *** fromIntegral) .
flip divMod 1000000 $
fromIntegral _udt_pic_pico + nanos * 1000
instance DateTimeMath UnixDateTimePicos Picos where
UnixDateTimePicos{..} `plus` Picos picos =
check "plus{UnixDateTimePicos,Picos}" .
uncurry UnixDateTimePicos .
((+ _udt_pic_base) *** fromIntegral) .
flip divMod 1000000 $
fromIntegral _udt_pic_pico + picos
instance Enum UnixDate where
succ = flip plus $ Day 1
pred = flip plus . Day $ 1
toEnum = check "toEnum{UnixDate}" . UnixDate . fromIntegral
fromEnum = fromIntegral . _ud_day_base
instance Enum UnixTime where
succ = flip plus $ Second 1
pred = flip plus . Second $ 1
toEnum = check "toEnum{UnixTime}" . UnixTime . fromIntegral
fromEnum = fromIntegral . _ut_sec_base
instance Enum UnixTimeMillis where
succ = flip plus $ Millis 1
pred = flip plus . Millis $ 1
toEnum = check "toEnum{UnixTimeMillis}" . UnixTimeMillis . fromIntegral
fromEnum = fromIntegral . _ut_mil_base
instance Enum UnixTimeMicros where
succ = flip plus $ Micros 1
pred = flip plus . Micros $ 1
toEnum = check "toEnum{UnixTimeMicros}" . UnixTimeMicros . fromIntegral
fromEnum = fromIntegral . _ut_mic_base
instance Enum UnixTimeNanos where
succ = flip plus $ Nanos 1
pred = flip plus . Nanos $ 1
toEnum = check "toEnum{UnixTimeNanos}" . UnixTimeNanos . fromIntegral
fromEnum = fromIntegral . _ut_nan_base
instance Enum UnixTimePicos where
succ = flip plus $ Picos 1
pred = flip plus . Picos $ 1
toEnum = check "toEnum{UnixTimePicos}" . UnixTimePicos . fromIntegral
fromEnum = fromIntegral . _ut_pic_base
instance Enum UnixDateTime where
succ = flip plus $ Second 1
pred = flip plus . Second $ 1
toEnum = check "toEnum{UnixDateTime}" . UnixDateTime . fromIntegral
fromEnum = fromIntegral . _udt_sec_base
instance Enum UnixDateTimeMillis where
succ = flip plus $ Millis 1
pred = flip plus . Millis $ 1
toEnum = check "toEnum{UnixDateTimeMillis}" . UnixDateTimeMillis . fromIntegral
fromEnum = fromIntegral . _udt_mil_base
instance Enum UnixDateTimeMicros where
succ = flip plus $ Micros 1
pred = flip plus . Micros $ 1
toEnum = check "toEnum{UnixDateTimeMicros}" . UnixDateTimeMicros . fromIntegral
fromEnum = fromIntegral . _udt_mic_base
createUnixDate :: Year -> Month -> Day -> UnixDate
createUnixDate year month day =
check "createUnixDate" $ UnixDate base
where Day base = epochToDate year month day
createUnixTime :: Hour -> Minute -> Second -> UnixTime
createUnixTime hour minute second =
check "createUnixTime" $ UnixTime base
where base = fromIntegral $ midnightToTime hour minute second
createUnixTimeMillis :: Hour -> Minute -> Second -> Millis -> UnixTimeMillis
createUnixTimeMillis hour minute second (Millis millis) =
check "createUnixTimeMillis" $ UnixTimeMillis base
where Second seconds = midnightToTime hour minute second
base = fromIntegral seconds * 1000 + fromIntegral millis
createUnixTimeMicros :: Hour -> Minute -> Second -> Micros -> UnixTimeMicros
createUnixTimeMicros hour minute second (Micros micros) =
check "createUnixTimeMicros" $ UnixTimeMicros base
where Second seconds = midnightToTime hour minute second
base = seconds * 1000000 + fromIntegral micros
createUnixTimeNanos :: Hour -> Minute -> Second -> Nanos -> UnixTimeNanos
createUnixTimeNanos hour minute second (Nanos nanos) =
check "createUnixTimeNanos" $ UnixTimeNanos base
where Second seconds = midnightToTime hour minute second
base = seconds * 1000000000 + fromIntegral nanos
createUnixTimePicos :: Hour -> Minute -> Second -> Picos -> UnixTimePicos
createUnixTimePicos hour minute second (Picos picos) =
check "createUnixTimePicos" $ UnixTimePicos base
where Second seconds = midnightToTime hour minute second
base = seconds * 1000000000000 + fromIntegral picos
createUnixDateTime :: Year -> Month -> Day -> Hour -> Minute -> Second -> UnixDateTime
createUnixDateTime year month day hour minute second =
check "createUnixDateTime" $ UnixDateTime base
where Second base = epochToTime year month day hour minute second
createUnixDateTimeMillis :: Year -> Month -> Day -> Hour -> Minute -> Second -> Millis -> UnixDateTimeMillis
createUnixDateTimeMillis year month day hour minute second (Millis millis) =
check "createUnixDateTimeMillis" $ UnixDateTimeMillis base
where Second seconds = epochToTime year month day hour minute second
base = seconds * 1000 + millis
createUnixDateTimeMicros :: Year -> Month -> Day -> Hour -> Minute -> Second -> Micros -> UnixDateTimeMicros
createUnixDateTimeMicros year month day hour minute second (Micros micros) =
check "createUnixDateTimeMicros" $ UnixDateTimeMicros base
where Second seconds = epochToTime year month day hour minute second
base = seconds * 1000000 + micros
createUnixDateTimeNanos :: Year -> Month -> Day -> Hour -> Minute -> Second -> Nanos -> UnixDateTimeNanos
createUnixDateTimeNanos year month day hour minute second (Nanos nanos) =
check "createUnixDateTimeNanos" $ UnixDateTimeNanos base nano
where (micros, nano) = fmap fromIntegral $ divMod nanos 1000
Second seconds = epochToTime year month day hour minute second
base = seconds * 1000000 + micros
createUnixDateTimePicos :: Year -> Month -> Day -> Hour -> Minute -> Second -> Picos -> UnixDateTimePicos
createUnixDateTimePicos year month day hour minute second (Picos picos) =
check "createUnixDateTimePicos" $ UnixDateTimePicos base pico
where (micros, pico) = fmap fromIntegral $ divMod picos 1000000
Second seconds = epochToTime year month day hour minute second
base = seconds * 1000000 + micros
decompYearToDate :: Day -> Bool -> (Month, Day)
decompYearToDate days leap =
if leap
then if days >= 182
then if days >= 274
then if days >= 335
then (December, days 334)
else if days >= 305
then (November, days 304)
else (October , days 273)
else if days >= 244
then (September, days 243)
else if days >= 213
then (August, days 212)
else (July , days 181)
else if days >= 091
then if days >= 152
then (June, days 151)
else if days >= 121
then (May , days 120)
else (April, days 090)
else if days >= 060
then (March, days 059)
else if days >= 031
then (February, days 030)
else (January , days + 001)
else if days >= 181
then if days >= 273
then if days >= 334
then (December, days 333)
else if days >= 304
then (November, days 303)
else (October , days 272)
else if days >= 243
then (September, days 242)
else if days >= 212
then (August, days 211)
else (July , days 180)
else if days >= 090
then if days >= 151
then (June, days 150)
else if days >= 120
then (May , days 119)
else (April, days 089)
else if days >= 059
then (March, days 058)
else if days >= 031
then (February, days 030)
else (January , days + 001)
decompUnixDate :: UnixDate -> DateStruct
decompUnixDate (UnixDate base) =
go 1970 $ Day base
where go :: Year -> Day -> DateStruct
go !year !days =
if days >= size
then go (year + 1) (days size)
else DateStruct year month mday wday
where wday = toEnum $ (fromIntegral base + 4) `mod` 7
leap = isLeapYear year
size = if leap then 366 else 365
(month, mday) = decompYearToDate days leap
decompUnixTime :: UnixTime -> TimeStruct
decompUnixTime (UnixTime base) =
TimeStruct hour mn sec
where (hour, mod1) = fromIntegral *** fromIntegral $ divMod base 3600
(mn , sec ) = fmap realToFrac $ divMod mod1 0060
decompUnixTimeMillis :: UnixTimeMillis -> TimeStruct
decompUnixTimeMillis (UnixTimeMillis base) =
TimeStruct hour mn $ sec + mill / 1000
where (hour, mod1) = fromIntegral *** fromIntegral $ divMod base 3600000
(mn , mod2) = divMod mod1 0060000
(sec , mill) = realToFrac *** realToFrac $ divMod mod2 0001000
decompUnixTimeMicros :: UnixTimeMicros -> TimeStruct
decompUnixTimeMicros (UnixTimeMicros base) =
TimeStruct hour mn $ sec + micr / 1000000
where (hour, mod1) = Hour *** Minute $ divMod base 3600000000
(mn , mod2) = divMod mod1 0060000000
(sec , micr) = realToFrac *** realToFrac $ divMod mod2 0001000000
decompUnixTimeNanos :: UnixTimeNanos -> TimeStruct
decompUnixTimeNanos (UnixTimeNanos base) =
TimeStruct hour mn $ sec + nano / 1000000000
where (hour, mod1) = Hour *** Minute $ divMod base 3600000000000
(mn , mod2) = divMod mod1 0060000000000
(sec , nano) = realToFrac *** realToFrac $ divMod mod2 0001000000000
decompUnixTimePicos :: UnixTimePicos -> TimeStruct
decompUnixTimePicos (UnixTimePicos base) =
TimeStruct hour mn $ sec + pico / 1000000000000
where (hour, mod1) = Hour *** Minute $ divMod base 3600000000000000
(mn , mod2) = divMod mod1 0060000000000000
(sec , pico) = realToFrac *** realToFrac $ divMod mod2 0001000000000000
decompUnixDateTime :: UnixDateTime -> DateTimeStruct
decompUnixDateTime (UnixDateTime base) =
DateTimeStruct _d_year _d_mon _d_mday _d_wday hour mn sec
where DateStruct{..} = decompUnixDate $ UnixDate date
(date, mod1) = fromIntegral *** Hour $ divMod base 86400
(hour, mod2) = fmap fromIntegral $ divMod mod1 03600
(mn , sec ) = fmap realToFrac $ divMod mod2 00060
decompUnixDateTimeMillis :: UnixDateTimeMillis -> DateTimeStruct
decompUnixDateTimeMillis (UnixDateTimeMillis base) =
DateTimeStruct _d_year _d_mon _d_mday _d_wday hour mn $ sec + mill / 1000
where DateStruct{..} = decompUnixDate $ UnixDate date
(date, mod1) = fromIntegral *** Hour $ divMod base 86400000
(hour, mod2) = fmap fromIntegral $ divMod mod1 03600000
(mn , mod3) = divMod mod2 00060000
(sec , mill) = realToFrac *** realToFrac $ divMod mod3 00001000
decompUnixDateTimeMicros :: UnixDateTimeMicros -> DateTimeStruct
decompUnixDateTimeMicros (UnixDateTimeMicros base) =
DateTimeStruct _d_year _d_mon _d_mday _d_wday hour mn $ sec + micr / 1000000
where DateStruct{..} = decompUnixDate $ UnixDate date
(date, mod1) = fromIntegral *** Hour $ divMod base 86400000000
(hour, mod2) = fmap fromIntegral $ divMod mod1 03600000000
(mn , mod3) = divMod mod2 00060000000
(sec , micr) = realToFrac *** realToFrac $ divMod mod3 00001000000
decompUnixDateTimeNanos :: UnixDateTimeNanos -> DateTimeStruct
decompUnixDateTimeNanos (UnixDateTimeNanos base nano) =
modify dt_sec (+ fromIntegral nano / 1000000000) . decompUnixDateTimeMicros $ UnixDateTimeMicros base
decompUnixDateTimePicos :: UnixDateTimePicos -> DateTimeStruct
decompUnixDateTimePicos (UnixDateTimePicos base pico) =
modify dt_sec (+ fromIntegral pico / 1000000000000) . decompUnixDateTimeMicros $ UnixDateTimeMicros base
instance Convertible UnixDateTime UnixDate where
safeConvert = Right . UnixDate . fromIntegral . flip div 00000086400 . _udt_sec_base
instance Convertible UnixDateTime UnixTime where
safeConvert = Right . UnixTime . fromIntegral . flip mod 00000086400 . _udt_sec_base
instance Convertible UnixDateTimeMillis UnixDate where
safeConvert = Right . UnixDate . fromIntegral . flip div 00086400000 . _udt_mil_base
instance Convertible UnixDateTimeMillis UnixTime where
safeConvert = Right . UnixTime . fromIntegral . flip mod 00086400000 . _udt_mil_base
instance Convertible UnixDateTimeMicros UnixDate where
safeConvert = Right . UnixDate . fromIntegral . flip div 86400000000 . _udt_mic_base
instance Convertible UnixDateTimeMicros UnixTime where
safeConvert = Right . UnixTime . fromIntegral . flip mod 86400000000 . _udt_mic_base
instance Convertible UnixDateTimeNanos UnixDate where
safeConvert = Right . UnixDate . fromIntegral . flip div 86400000000 . _udt_nan_base
instance Convertible UnixDateTimeNanos UnixTime where
safeConvert = Right . UnixTime . fromIntegral . flip mod 86400000000 . _udt_nan_base
instance Convertible UnixDateTimePicos UnixDate where
safeConvert = Right . UnixDate . fromIntegral . flip div 86400000000 . _udt_pic_base
instance Convertible UnixDateTimePicos UnixTime where
safeConvert = Right . UnixTime . fromIntegral . flip mod 86400000000 . _udt_pic_base
instance Date UnixDate where
toDateStruct = decompUnixDate
fromDateStruct DateStruct{..} =
createUnixDate _d_year _d_mon _d_mday
instance Date UnixDateTime where
toDateStruct = decompUnixDate . convert
fromDateStruct DateStruct{..} =
createUnixDateTime _d_year _d_mon _d_mday 0 0 0
instance Date UnixDateTimeMillis where
toDateStruct = decompUnixDate . convert
fromDateStruct DateStruct{..} =
createUnixDateTimeMillis _d_year _d_mon _d_mday 0 0 0 0
instance Date UnixDateTimeMicros where
toDateStruct = decompUnixDate . convert
fromDateStruct DateStruct{..} =
createUnixDateTimeMicros _d_year _d_mon _d_mday 0 0 0 0
instance Date UnixDateTimeNanos where
toDateStruct = decompUnixDate . convert
fromDateStruct DateStruct{..} =
createUnixDateTimeNanos _d_year _d_mon _d_mday 0 0 0 0
instance Date UnixDateTimePicos where
toDateStruct = decompUnixDate . convert
fromDateStruct DateStruct{..} =
createUnixDateTimePicos _d_year _d_mon _d_mday 0 0 0 0
instance Time UnixTime where
toTimeStruct = decompUnixTime
fromTimeStruct TimeStruct{..} =
createUnixTime _t_hour _t_min sec
where sec = round _t_sec
instance Time UnixTimeMillis where
toTimeStruct = decompUnixTimeMillis
fromTimeStruct TimeStruct{..} =
createUnixTimeMillis _t_hour _t_min sec mil
where (sec, mil) = properFracMillis _t_sec
instance Time UnixTimeMicros where
toTimeStruct = decompUnixTimeMicros
fromTimeStruct TimeStruct{..} =
createUnixTimeMicros _t_hour _t_min sec mic
where (sec, mic) = properFracMicros _t_sec
instance Time UnixTimeNanos where
toTimeStruct = decompUnixTimeNanos
fromTimeStruct TimeStruct{..} =
createUnixTimeNanos _t_hour _t_min sec nan
where (sec, nan) = properFracNanos _t_sec
instance Time UnixTimePicos where
toTimeStruct = decompUnixTimePicos
fromTimeStruct TimeStruct{..} =
createUnixTimePicos _t_hour _t_min sec pic
where (sec, pic) = properFracPicos _t_sec
instance Time UnixDateTime where
toTimeStruct = decompUnixTime . convert
fromTimeStruct TimeStruct{..} =
createUnixDateTime 1970 January 1 _t_hour _t_min sec
where sec = round _t_sec
instance Time UnixDateTimeMillis where
toTimeStruct = decompUnixTime . convert
fromTimeStruct TimeStruct{..} =
createUnixDateTimeMillis 1970 January 1 _t_hour _t_min sec mil
where (sec, mil) = properFracMillis _t_sec
instance Time UnixDateTimeMicros where
toTimeStruct = decompUnixTime . convert
fromTimeStruct TimeStruct{..} =
createUnixDateTimeMicros 1970 January 1 _t_hour _t_min sec mic
where (sec, mic) = properFracMicros _t_sec
instance Time UnixDateTimeNanos where
toTimeStruct = decompUnixTime . convert
fromTimeStruct TimeStruct{..} =
createUnixDateTimeNanos 1970 January 1 _t_hour _t_min sec nan
where (sec, nan) = properFracNanos _t_sec
instance Time UnixDateTimePicos where
toTimeStruct = decompUnixTime . convert
fromTimeStruct TimeStruct{..} =
createUnixDateTimePicos 1970 January 1 _t_hour _t_min sec pic
where (sec, pic) = properFracPicos _t_sec
instance DateTime UnixDateTime where
toDateTimeStruct = decompUnixDateTime
fromDateTimeStruct DateTimeStruct{..} =
createUnixDateTime _dt_year _dt_mon _dt_mday _dt_hour _dt_min sec
where sec = round _dt_sec :: Second
instance DateTime UnixDateTimeMillis where
toDateTimeStruct = decompUnixDateTimeMillis
fromDateTimeStruct DateTimeStruct{..} =
createUnixDateTimeMillis _dt_year _dt_mon _dt_mday _dt_hour _dt_min sec mil
where (sec, mil) = properFracMillis _dt_sec
instance DateTime UnixDateTimeMicros where
toDateTimeStruct = decompUnixDateTimeMicros
fromDateTimeStruct DateTimeStruct{..} =
createUnixDateTimeMicros _dt_year _dt_mon _dt_mday _dt_hour _dt_min sec mic
where (sec, mic) = properFracMicros _dt_sec
instance DateTime UnixDateTimeNanos where
toDateTimeStruct = decompUnixDateTimeNanos
fromDateTimeStruct DateTimeStruct{..} =
createUnixDateTimeNanos _dt_year _dt_mon _dt_mday _dt_hour _dt_min sec nan
where (sec, nan) = properFracNanos _dt_sec
instance DateTime UnixDateTimePicos where
toDateTimeStruct = decompUnixDateTimePicos
fromDateTimeStruct DateTimeStruct{..} =
createUnixDateTimePicos _dt_year _dt_mon _dt_mday _dt_hour _dt_min sec pic
where (sec, pic) = properFracPicos _dt_sec
instance Show UnixDate where
show date = printf "%04d-%02d-%02d" _d_year mon _d_mday
where DateStruct{..} = toDateStruct date
mon = fromEnum _d_mon + 1
instance Show UnixTime where
show time = printf "%02d:%02d:%02d" _t_hour _t_min sec
where TimeStruct{..} = toTimeStruct time
sec = round _t_sec :: Second
instance Show UnixTimeMillis where
show time = printf "%02d:%02d:%02d.%03d" _t_hour _t_min sec mil
where TimeStruct{..} = toTimeStruct time
(sec, mil) = properFracMillis _t_sec
instance Show UnixTimeMicros where
show time = printf "%02d:%02d:%02d.%06d" _t_hour _t_min sec mic
where TimeStruct{..} = toTimeStruct time
(sec, mic) = properFracMicros _t_sec
instance Show UnixTimeNanos where
show time = printf "%02d:%02d:%02d.%09d" _t_hour _t_min sec nan
where TimeStruct{..} = toTimeStruct time
(sec, nan) = properFracNanos _t_sec
instance Show UnixTimePicos where
show time = printf "%02d:%02d:%02d.%012d" _t_hour _t_min sec pic
where TimeStruct{..} = toTimeStruct time
(sec, pic) = properFracPicos _t_sec
instance Show UnixDateTime where
show time = printf "%04d-%02d-%02d %02d:%02d:%02d" _dt_year mon _dt_mday _dt_hour _dt_min sec
where DateTimeStruct{..} = toDateTimeStruct time
mon = fromEnum _dt_mon + 1
sec = round _dt_sec :: Second
instance Show UnixDateTimeMillis where
show time = printf "%04d-%02d-%02d %02d:%02d:%02d.%03d" _dt_year mon _dt_mday _dt_hour _dt_min sec mil
where DateTimeStruct{..} = toDateTimeStruct time
mon = fromEnum _dt_mon + 1
(sec, mil) = properFracMillis _dt_sec
instance Show UnixDateTimeMicros where
show time = printf "%04d-%02d-%02d %02d:%02d:%02d.%06d" _dt_year mon _dt_mday _dt_hour _dt_min sec mic
where DateTimeStruct{..} = toDateTimeStruct time
mon = fromEnum _dt_mon + 1
(sec, mic) = properFracMicros _dt_sec
instance Show UnixDateTimeNanos where
show time = printf "%04d-%02d-%02d %02d:%02d:%02d.%09d" _dt_year mon _dt_mday _dt_hour _dt_min sec nan
where DateTimeStruct{..} = toDateTimeStruct time
mon = fromEnum _dt_mon + 1
(sec, nan) = properFracNanos _dt_sec
instance Show UnixDateTimePicos where
show time = printf "%04d-%02d-%02d %02d:%02d:%02d.%012d" _dt_year mon _dt_mday _dt_hour _dt_min sec pic
where DateTimeStruct{..} = toDateTimeStruct time
mon = fromEnum _dt_mon + 1
(sec, pic) = properFracPicos _dt_sec
getCurrentUnixDate :: IO UnixDate
getCurrentUnixDate = getCurrentUnixDateTime >>= return . convert
getCurrentUnixTime :: IO UnixTime
getCurrentUnixTime = getCurrentUnixDateTime >>= return . convert
getCurrentUnixTimeMillis :: IO UnixTimeMillis
getCurrentUnixTimeMillis =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixTimeMillis . fromIntegral $ (base `mod` 86400) * 1000 + micr `div` 1000
getResult _ _ = error "getCurrentUnixTimeMillis: unknown"
getCurrentUnixTimeMicros :: IO UnixTimeMicros
getCurrentUnixTimeMicros =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixTimeMicros $ (base `mod` 86400) * 1000000 + micr
getResult _ _ = error "getCurrentUnixTimeMicros: unknown"
getCurrentUnixTimeNanos :: IO UnixTimeNanos
getCurrentUnixTimeNanos =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixTimeNanos $ (base `mod` 86400) * 1000000000 + micr * 1000
getResult _ _ = error "getCurrentUnixTimeNanos: unknown"
getCurrentUnixTimePicos :: IO UnixTimePicos
getCurrentUnixTimePicos =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixTimePicos $ (base `mod` 86400) * 1000000000000 + micr * 1000000
getResult _ _ = error "getCurrentUnixTimePicos: unknown"
getCurrentUnixDateTime :: IO UnixDateTime
getCurrentUnixDateTime =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek $ castPtr ptr
getResult _ _ = error "getCurrentUnixDateTime: unknown"
getCurrentUnixDateTimeMillis :: IO UnixDateTimeMillis
getCurrentUnixDateTimeMillis =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixDateTimeMillis $ base * 1000 + micr `div` 1000
getResult _ _ = error "getCurrentUnixDateTimeMillis: unknown"
getCurrentUnixDateTimeMicros :: IO UnixDateTimeMicros
getCurrentUnixDateTimeMicros =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixDateTimeMicros $ base * 1000000 + micr
getResult _ _ = error "getCurrentUnixDateTimeMicros: unknown"
getCurrentUnixDateTimeNanos :: IO UnixDateTimeNanos
getCurrentUnixDateTimeNanos =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixDateTimeNanos (base * 1000000 + micr) 0
getResult _ _ = error "getCurrentUnixDateTimeNanos: unknown"
getCurrentUnixDateTimePicos :: IO UnixDateTimePicos
getCurrentUnixDateTimePicos =
with (C'timeval 0 0) $ \ ptr ->
c'gettimeofday ptr nullPtr >>= getResult ptr
where getResult ptr 0 = peek ptr >>= \ (C'timeval (CLong base) (CLong micr)) ->
return $! UnixDateTimePicos (base * 1000000 + micr) 0
getResult _ _ = error "getCurrentUnixDateTimePicos: unknown"
fromNanos :: UnixDateTimeNanos -> Integer
fromNanos (UnixDateTimeNanos base nano) = toInteger base * 0001000 + toInteger nano
fromPicos :: UnixDateTimePicos -> Integer
fromPicos (UnixDateTimePicos base pico) = toInteger base * 1000000 + toInteger pico
toNanos :: Integer -> UnixDateTimeNanos
toNanos = uncurry UnixDateTimeNanos . (fromInteger *** fromInteger) . flip divMod 0001000
toPicos :: Integer -> UnixDateTimePicos
toPicos = uncurry UnixDateTimePicos . (fromInteger *** fromInteger) . flip divMod 1000000
instance Duration UnixDate Day where
duration (UnixDate old) (UnixDate new) = Day (new old)
instance Duration UnixTime Hour where
duration (UnixTime old) (UnixTime new) = fromIntegral (new old) `div` 3600
instance Duration UnixTime Minute where
duration (UnixTime old) (UnixTime new) = fromIntegral (new old) `div` 60
instance Duration UnixTime Second where
duration (UnixTime old) (UnixTime new) = fromIntegral (new old)
instance Duration UnixTimeMillis Hour where
duration (UnixTimeMillis old) (UnixTimeMillis new) = fromIntegral (new old) `div` 3600000
instance Duration UnixTimeMillis Minute where
duration (UnixTimeMillis old) (UnixTimeMillis new) = fromIntegral (new old) `div` 60000
instance Duration UnixTimeMillis Second where
duration (UnixTimeMillis old) (UnixTimeMillis new) = fromIntegral (new old) `div` 1000
instance Duration UnixTimeMillis Millis where
duration (UnixTimeMillis old) (UnixTimeMillis new) = fromIntegral (new old)
instance Duration UnixTimeMicros Hour where
duration (UnixTimeMicros old) (UnixTimeMicros new) = Hour (new old) `div` 3600000000
instance Duration UnixTimeMicros Minute where
duration (UnixTimeMicros old) (UnixTimeMicros new) = Minute (new old) `div` 60000000
instance Duration UnixTimeMicros Second where
duration (UnixTimeMicros old) (UnixTimeMicros new) = Second (new old) `div` 1000000
instance Duration UnixTimeMicros Millis where
duration (UnixTimeMicros old) (UnixTimeMicros new) = Millis (new old) `div` 1000
instance Duration UnixTimeMicros Micros where
duration (UnixTimeMicros old) (UnixTimeMicros new) = Micros (new old)
instance Duration UnixTimeNanos Hour where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Hour (new old) `div` 3600000000000
instance Duration UnixTimeNanos Minute where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Minute (new old) `div` 60000000000
instance Duration UnixTimeNanos Second where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Second (new old) `div` 1000000000
instance Duration UnixTimeNanos Millis where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Millis (new old) `div` 1000000
instance Duration UnixTimeNanos Micros where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Micros (new old) `div` 1000
instance Duration UnixTimeNanos Nanos where
duration (UnixTimeNanos old) (UnixTimeNanos new) = Nanos (new old)
instance Duration UnixTimePicos Hour where
duration (UnixTimePicos old) (UnixTimePicos new) = Hour (new old) `div` 3600000000000000
instance Duration UnixTimePicos Minute where
duration (UnixTimePicos old) (UnixTimePicos new) = Minute (new old) `div` 60000000000000
instance Duration UnixTimePicos Second where
duration (UnixTimePicos old) (UnixTimePicos new) = Second (new old) `div` 1000000000000
instance Duration UnixTimePicos Millis where
duration (UnixTimePicos old) (UnixTimePicos new) = Millis (new old) `div` 1000000000
instance Duration UnixTimePicos Micros where
duration (UnixTimePicos old) (UnixTimePicos new) = Micros (new old) `div` 1000000
instance Duration UnixTimePicos Nanos where
duration (UnixTimePicos old) (UnixTimePicos new) = Nanos (new old) `div` 1000
instance Duration UnixTimePicos Picos where
duration (UnixTimePicos old) (UnixTimePicos new) = Picos (new old)
instance Duration UnixDateTime Day where
duration (UnixDateTime old) (UnixDateTime new) = fromIntegral $ (new old) `div` 86400
instance Duration UnixDateTime Hour where
duration (UnixDateTime old) (UnixDateTime new) = Hour (new old) `div` 3600
instance Duration UnixDateTime Minute where
duration (UnixDateTime old) (UnixDateTime new) = Minute (new old) `div` 60
instance Duration UnixDateTime Second where
duration (UnixDateTime old) (UnixDateTime new) = Second (new old)
instance Duration UnixDateTimeMillis Day where
duration (UnixDateTimeMillis old) (UnixDateTimeMillis new) = fromIntegral $ (new old) `div` 86400000
instance Duration UnixDateTimeMillis Hour where
duration (UnixDateTimeMillis old) (UnixDateTimeMillis new) = Hour (new old) `div` 3600000
instance Duration UnixDateTimeMillis Minute where
duration (UnixDateTimeMillis old) (UnixDateTimeMillis new) = Minute (new old) `div` 60000
instance Duration UnixDateTimeMillis Second where
duration (UnixDateTimeMillis old) (UnixDateTimeMillis new) = Second (new old) `div` 1000
instance Duration UnixDateTimeMillis Millis where
duration (UnixDateTimeMillis old) (UnixDateTimeMillis new) = Millis (new old)
instance Duration UnixDateTimeMicros Day where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = fromIntegral $ (new old) `div` 86400000000
instance Duration UnixDateTimeMicros Hour where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = Hour (new old) `div` 3600000000
instance Duration UnixDateTimeMicros Minute where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = Minute (new old) `div` 60000000
instance Duration UnixDateTimeMicros Second where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = Second (new old) `div` 1000000
instance Duration UnixDateTimeMicros Millis where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = Millis (new old) `div` 1000
instance Duration UnixDateTimeMicros Micros where
duration (UnixDateTimeMicros old) (UnixDateTimeMicros new) = Micros (new old)
instance Duration UnixDateTimeNanos Day where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = fromIntegral $ (new old) `div` 86400000000
instance Duration UnixDateTimeNanos Hour where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = Hour (new old) `div` 3600000000
instance Duration UnixDateTimeNanos Minute where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = Minute (new old) `div` 60000000
instance Duration UnixDateTimeNanos Second where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = Second (new old) `div` 1000000
instance Duration UnixDateTimeNanos Millis where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = Millis (new old) `div` 1000
instance Duration UnixDateTimeNanos Micros where
duration (UnixDateTimeNanos old _) (UnixDateTimeNanos new _) = Micros (new old)
instance Duration UnixDateTimeNanos Nanos where
duration old new =
if res < toInteger (maxBound::Int64) then fromInteger res
else error "duration{UnixDateTimeNanos,Nanos}: integer overflow"
where res = (fromNanos new fromNanos old)
instance Duration UnixDateTimePicos Day where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = fromIntegral $ (new old) `div` 86400000000
instance Duration UnixDateTimePicos Hour where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = Hour (new old) `div` 3600000000
instance Duration UnixDateTimePicos Minute where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = Minute (new old) `div` 60000000
instance Duration UnixDateTimePicos Second where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = Second (new old) `div` 1000000
instance Duration UnixDateTimePicos Millis where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = Millis (new old) `div` 1000
instance Duration UnixDateTimePicos Micros where
duration (UnixDateTimePicos old _) (UnixDateTimePicos new _) = Micros (new old)
instance Duration UnixDateTimePicos Nanos where
duration old new =
if res < toInteger (maxBound::Int64) then fromInteger res
else error "duration{UnixDateTimePicos,Nanos}: integer overflow"
where res = (fromPicos new fromPicos old) `div` 1000
instance Duration UnixDateTimePicos Picos where
duration old new =
if res < toInteger (maxBound::Int64) then fromInteger res
else error "duration{UnixDateTimePicos,Picos}: integer overflow"
where res = (fromPicos new fromPicos old)
instance Random UnixDate where
random = first toEnum . randomR (0,2932896)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixTime where
random = first toEnum . randomR (0,86399)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixTimeMillis where
random = first toEnum . randomR (0,86399999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixTimeMicros where
random = first toEnum . randomR (0,86399999999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixTimeNanos where
random = first toEnum . randomR (0,86399999999999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixTimePicos where
random = first toEnum . randomR (0,86399999999999999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixDateTime where
random = first toEnum . randomR (0,253402300799)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixDateTimeMillis where
random = first toEnum . randomR (0,253402300799999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixDateTimeMicros where
random = first toEnum . randomR (0,253402300799999999)
randomR (a,b) = first toEnum . randomR (fromEnum a, fromEnum b)
instance Random UnixDateTimeNanos where
random = first toNanos . randomR (0,253402300799999999999)
randomR (a,b) = first toNanos . randomR (fromNanos a, fromNanos b)
instance Random UnixDateTimePicos where
random = first toPicos . randomR (0,253402300799999999999999)
randomR (a,b) = first toPicos . randomR (fromPicos a, fromPicos b)
prettyUnixDate :: (Unix d, Date d) => d -> String
prettyUnixDate date =
printf "%s, %s %s, %04d" wday mon mday _d_year
where DateStruct{..} = toDateStruct date
wday = show _d_wday
mon = show _d_mon
mday = show _d_mday ++ showSuffix _d_mday
prettyUnixTime :: (Unix t, Time t) => t -> String
prettyUnixTime time =
printf "%d:%02d %s" hour _t_min ampm
where TimeStruct{..} = toTimeStruct time
ampm = showPeriod _t_hour
hour | _t_hour == 00 = 12
| _t_hour <= 12 = _t_hour
| otherwise = _t_hour 12
prettyUnixDateTime :: (Unix dt, DateTime dt) => dt -> String
prettyUnixDateTime time =
printf str hour _dt_min ampm wday mon mday _dt_year
where DateTimeStruct{..} = toDateTimeStruct time
str = "%d:%02d %s, %s, %s %s, %04d"
wday = show _dt_wday
mon = show _dt_mon
mday = show _dt_mday ++ showSuffix _dt_mday
ampm = showPeriod _dt_hour
hour | _dt_hour == 00 = 12
| _dt_hour <= 12 = _dt_hour
| otherwise = _dt_hour 12
check :: forall a . Bounded a => Ord a => Unix a => String -> a -> a
check f x =
if minBound <= x && x <= maxBound then x
else error $ f ++ ": base (" ++ base ++ ") out of bounds (" ++ bounds ++ ")"
where base = show (unixBase x)
bounds = show (unixBase (minBound::a)) ++ "," ++ show (unixBase (maxBound::a))