{-# LANGUAGE Safe #-}
module System.Time.Utils(
timelocal,
timegm,
timeDiffToSecs,
epoch,
epochToClockTime,
clockTimeToEpoch,
renderSecs, renderTD
)
where
import safe Data.Ratio ( (%) )
import safe System.Time
( diffClockTimes,
normalizeTimeDiff,
toCalendarTime,
toClockTime,
CalendarTime(..),
ClockTime(..),
Day(Thursday),
Month(January),
TimeDiff(TimeDiff, tdSec, tdMin, tdHour, tdDay, tdMonth, tdYear) )
epoch :: CalendarTime
epoch :: CalendarTime
epoch = CalendarTime :: Int
-> Month
-> Int
-> Int
-> Int
-> Int
-> Integer
-> Day
-> Int
-> String
-> Int
-> Bool
-> CalendarTime
CalendarTime { ctYear :: Int
ctYear = Int
1970, ctMonth :: Month
ctMonth = Month
January,
ctDay :: Int
ctDay = Int
1, ctHour :: Int
ctHour = Int
0, ctMin :: Int
ctMin = Int
0, ctSec :: Int
ctSec = Int
0,
ctPicosec :: Integer
ctPicosec = Integer
0, ctWDay :: Day
ctWDay = Day
Thursday, ctYDay :: Int
ctYDay = Int
0,
ctTZName :: String
ctTZName = String
"UTC", ctTZ :: Int
ctTZ = Int
0, ctIsDST :: Bool
ctIsDST = Bool
False}
timegm :: CalendarTime -> Integer
timegm :: CalendarTime -> Integer
timegm CalendarTime
ct =
TimeDiff -> Integer
timeDiffToSecs (ClockTime -> ClockTime -> TimeDiff
diffClockTimes (CalendarTime -> ClockTime
toClockTime CalendarTime
ct) (CalendarTime -> ClockTime
toClockTime CalendarTime
epoch))
timelocal :: CalendarTime -> IO Integer
timelocal :: CalendarTime -> IO Integer
timelocal CalendarTime
ct =
do CalendarTime
guessct <- ClockTime -> IO CalendarTime
toCalendarTime ClockTime
guesscl
let newct :: CalendarTime
newct = CalendarTime
ct {ctTZ :: Int
ctTZ = CalendarTime -> Int
ctTZ CalendarTime
guessct}
Integer -> IO Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> IO Integer) -> Integer -> IO Integer
forall a b. (a -> b) -> a -> b
$ CalendarTime -> Integer
timegm CalendarTime
newct
where guesscl :: ClockTime
guesscl = CalendarTime -> ClockTime
toClockTime CalendarTime
ct
timeDiffToSecs :: TimeDiff -> Integer
timeDiffToSecs :: TimeDiff -> Integer
timeDiffToSecs TimeDiff
td =
(Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdSec TimeDiff
td) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+
Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* ((Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdMin TimeDiff
td) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+
Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* ((Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdHour TimeDiff
td) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+
Integer
24 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* ((Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdDay TimeDiff
td) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+
Integer
30 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* ((Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdMonth TimeDiff
td) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+
Integer
365 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ TimeDiff -> Int
tdYear TimeDiff
td)))))
epochToClockTime :: Real a => a -> ClockTime
epochToClockTime :: a -> ClockTime
epochToClockTime a
x =
Integer -> Integer -> ClockTime
TOD Integer
seconds Integer
secfrac
where ratval :: Rational
ratval = a -> Rational
forall a. Real a => a -> Rational
toRational a
x
seconds :: Integer
seconds = Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor Rational
ratval
secfrac :: Integer
secfrac = Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational -> Integer) -> Rational -> Integer
forall a b. (a -> b) -> a -> b
$ (Rational
ratval Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- (Integer
seconds Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1) ) Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
picosecondfactor
picosecondfactor :: Rational
picosecondfactor = Rational
10 Rational -> Integer -> Rational
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
12 :: Integer)
clockTimeToEpoch :: Num a => ClockTime -> a
clockTimeToEpoch :: ClockTime -> a
clockTimeToEpoch (TOD Integer
sec Integer
_) = Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
sec
renderSecs :: Integer -> String
renderSecs :: Integer -> String
renderSecs Integer
i = TimeDiff -> String
renderTD (TimeDiff -> String) -> TimeDiff -> String
forall a b. (a -> b) -> a -> b
$ ClockTime -> ClockTime -> TimeDiff
diffClockTimes (Integer -> Integer -> ClockTime
TOD Integer
i Integer
0) (Integer -> Integer -> ClockTime
TOD Integer
0 Integer
0)
renderTD :: TimeDiff -> String
renderTD :: TimeDiff -> String
renderTD TimeDiff
itd =
case [(Int, Char)]
workinglist of
[] -> String
"0s"
[(Int, Char)]
_ -> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> ([(Int, Char)] -> [String]) -> [(Int, Char)] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Char) -> String) -> [(Int, Char)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\(Int
q, Char
s) -> Int -> String
forall a. Show a => a -> String
show Int
q String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
s]) ([(Int, Char)] -> String) -> [(Int, Char)] -> String
forall a b. (a -> b) -> a -> b
$ [(Int, Char)]
workinglist
where td :: TimeDiff
td = TimeDiff -> TimeDiff
normalizeTimeDiff TimeDiff
itd
suffixlist :: String
suffixlist = String
"yMdhms"
quantlist :: [Int]
quantlist = (\(TimeDiff Int
y Int
mo Int
d Int
h Int
m Int
s Integer
_) -> [Int
y, Int
mo, Int
d, Int
h, Int
m, Int
s]) TimeDiff
td
zippedlist :: [(Int, Char)]
zippedlist = [Int] -> String -> [(Int, Char)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
quantlist String
suffixlist
workinglist :: [(Int, Char)]
workinglist = Int -> [(Int, Char)] -> [(Int, Char)]
forall a. Int -> [a] -> [a]
take Int
2 ([(Int, Char)] -> [(Int, Char)])
-> ([(Int, Char)] -> [(Int, Char)])
-> [(Int, Char)]
-> [(Int, Char)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Char) -> Bool) -> [(Int, Char)] -> [(Int, Char)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (\(Int
q, Char
_) -> Int
q Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) ([(Int, Char)] -> [(Int, Char)]) -> [(Int, Char)] -> [(Int, Char)]
forall a b. (a -> b) -> a -> b
$ [(Int, Char)]
zippedlist