format everything with hindent
[packages/time.git] / lib / Data / Time / Clock / System.hs
1 -- | Fast access to the system clock.
2 module Data.Time.Clock.System
3 ( systemEpochDay
4 , SystemTime(..)
5 , truncateSystemTimeLeapSecond
6 , getSystemTime
7 , systemToUTCTime
8 , utcToSystemTime
9 , systemToTAITime
10 ) where
11
12 import Data.Int (Int64)
13 import Data.Time.Calendar.Days
14 import Data.Time.Clock.Internal.AbsoluteTime
15 import Data.Time.Clock.Internal.DiffTime
16 import Data.Time.Clock.Internal.SystemTime
17 import Data.Time.Clock.Internal.UTCTime
18
19 -- | Map leap-second values to the start of the following second.
20 -- The resulting 'systemNanoseconds' will always be in the range 0 to 1E9-1.
21 truncateSystemTimeLeapSecond :: SystemTime -> SystemTime
22 truncateSystemTimeLeapSecond (MkSystemTime seconds nanoseconds)
23 | nanoseconds >= 1000000000 = MkSystemTime (succ seconds) 0
24 truncateSystemTimeLeapSecond t = t
25
26 -- | Convert 'SystemTime' to 'UTCTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' UTC.
27 systemToUTCTime :: SystemTime -> UTCTime
28 systemToUTCTime (MkSystemTime seconds nanoseconds) = let
29 days :: Int64
30 timeSeconds :: Int64
31 (days, timeSeconds) = seconds `divMod` 86400
32 day :: Day
33 day = addDays (fromIntegral days) systemEpochDay
34 timeNanoseconds :: Int64
35 timeNanoseconds = timeSeconds * 1000000000 + (fromIntegral nanoseconds)
36 timePicoseconds :: Int64
37 timePicoseconds = timeNanoseconds * 1000
38 time :: DiffTime
39 time = picosecondsToDiffTime $ fromIntegral timePicoseconds
40 in UTCTime day time
41
42 -- | Convert 'UTCTime' to 'SystemTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' UTC.
43 utcToSystemTime :: UTCTime -> SystemTime
44 utcToSystemTime (UTCTime day time) = let
45 days :: Int64
46 days = fromIntegral $ diffDays day systemEpochDay
47 timePicoseconds :: Int64
48 timePicoseconds = fromIntegral $ diffTimeToPicoseconds time
49 timeNanoseconds :: Int64
50 timeNanoseconds = timePicoseconds `div` 1000
51 timeSeconds :: Int64
52 nanoseconds :: Int64
53 (timeSeconds, nanoseconds) =
54 if timeNanoseconds >= 86400000000000
55 then (86399, timeNanoseconds - 86399000000000)
56 else timeNanoseconds `divMod` 1000000000
57 seconds :: Int64
58 seconds = days * 86400 + timeSeconds
59 in MkSystemTime seconds $ fromIntegral nanoseconds
60
61 systemEpochAbsolute :: AbsoluteTime
62 systemEpochAbsolute = taiNominalDayStart systemEpochDay
63
64 -- | Convert 'SystemTime' to 'AbsoluteTime', matching zero 'SystemTime' to midnight of 'systemEpochDay' TAI.
65 systemToTAITime :: SystemTime -> AbsoluteTime
66 systemToTAITime (MkSystemTime s ns) = let
67 diff :: DiffTime
68 diff = (fromIntegral s) + (fromIntegral ns) * 1E-9
69 in addAbsoluteTime diff systemEpochAbsolute
70
71 -- | The day of the epoch of 'SystemTime', 1970-01-01
72 systemEpochDay :: Day
73 systemEpochDay = ModifiedJulianDay 40587