1{-# LANGUAGE CPP, DeriveDataTypeable #-}
2module Data.Time.LocalTime.Compat (
3    -- * Time zones
4    TimeZone(..),timeZoneOffsetString,timeZoneOffsetString',minutesToTimeZone,hoursToTimeZone,utc,
5
6    -- getting the locale time zone
7    getTimeZone,getCurrentTimeZone,
8
9    -- * Time of day
10    TimeOfDay(..),midnight,midday,makeTimeOfDayValid,
11    timeToDaysAndTimeOfDay,daysAndTimeOfDayToTime,
12    utcToLocalTimeOfDay,localToUTCTimeOfDay,
13    timeToTimeOfDay,timeOfDayToTime,
14    dayFractionToTimeOfDay,timeOfDayToDayFraction,
15    pastMidnight, sinceMidnight,
16
17    -- * CalendarDiffTime
18    CalendarDiffTime (..),
19    calendarTimeDays, calendarTimeTime, scaleCalendarDiffTime,
20
21    -- * Local Time
22    LocalTime(..),
23
24    addLocalTime,diffLocalTime,
25
26    -- converting UTC and UT1 times to LocalTime
27    utcToLocalTime,localTimeToUTC,ut1ToLocalTime,localTimeToUT1,
28
29    -- * Zoned Time
30    ZonedTime(..),utcToZonedTime,zonedTimeToUTC,getZonedTime,utcToLocalZonedTime,
31    ) where
32
33import Data.Time.Orphans ()
34
35import Data.Time.LocalTime
36import Data.Time.Clock.Compat
37import Data.Time.Calendar.Compat
38
39import Data.Fixed (Pico (..), showFixed, divMod')
40import Data.Monoid (Monoid (..))
41import Data.Data (Data, Typeable)
42import Data.Semigroup (Semigroup (..))
43
44import Control.DeepSeq (NFData (..))
45
46-------------------------------------------------------------------------------
47-- TimeOfDay
48-------------------------------------------------------------------------------
49
50#if !MIN_VERSION_time(1,9,0)
51
52-- | Convert a period of time into a count of days and a time of day since midnight.
53-- The time of day will never have a leap second.
54timeToDaysAndTimeOfDay :: NominalDiffTime -> (Integer,TimeOfDay)
55timeToDaysAndTimeOfDay dt = let
56    s = realToFrac dt
57    (m,ms) = divMod' s 60
58    (h,hm) = divMod' m 60
59    (d,dh) = divMod' h 24
60    in (d,TimeOfDay dh hm ms)
61
62-- | Convert a count of days and a time of day since midnight into a period of time.
63daysAndTimeOfDayToTime :: Integer -> TimeOfDay -> NominalDiffTime
64daysAndTimeOfDayToTime d (TimeOfDay dh hm ms) = (+) (realToFrac ms) $ (*) 60 $ (+) (realToFrac hm) $ (*) 60 $ (+) (realToFrac dh) $ (*) 24 $ realToFrac d
65
66#endif
67
68#if !MIN_VERSION_time(1,10,0)
69-- | Same as 'timeToTimeOfDay'.
70pastMidnight :: DiffTime -> TimeOfDay
71pastMidnight = timeToTimeOfDay
72
73-- | Same as 'timeOfDayToTime'.
74sinceMidnight :: TimeOfDay -> DiffTime
75sinceMidnight = timeOfDayToTime
76#endif
77
78-------------------------------------------------------------------------------
79-- CalendarDiffTime
80-------------------------------------------------------------------------------
81
82#if MIN_VERSION_time(1,9,0) && !MIN_VERSION_base(1,9,2)
83deriving instance Typeable CalendarDiffTime
84deriving instance Data CalendarDiffTime
85#endif
86
87#if !MIN_VERSION_time(1,9,2)
88
89data CalendarDiffTime = CalendarDiffTime
90    { ctMonths :: Integer
91    , ctTime :: NominalDiffTime
92    } deriving (Eq,
93    Data
94    ,Typeable
95    )
96
97-- | Additive
98instance Semigroup CalendarDiffTime where
99    CalendarDiffTime m1 d1 <> CalendarDiffTime m2 d2 = CalendarDiffTime (m1 + m2) (d1 + d2)
100
101instance Monoid CalendarDiffTime where
102    mempty = CalendarDiffTime 0 0
103    mappend = (<>)
104
105instance NFData CalendarDiffTime where
106    rnf (CalendarDiffTime x y) = rnf x `seq` rnf y
107
108instance Show CalendarDiffTime where
109    show (CalendarDiffTime m t) = "P" ++ show m ++ "MT" ++ showFixed True (realToFrac t :: Pico) ++ "S"
110
111calendarTimeDays :: CalendarDiffDays -> CalendarDiffTime
112calendarTimeDays (CalendarDiffDays m d) = CalendarDiffTime m $ fromInteger d * nominalDay
113
114calendarTimeTime :: NominalDiffTime -> CalendarDiffTime
115calendarTimeTime dt = CalendarDiffTime 0 dt
116
117-- | Scale by a factor. Note that @scaleCalendarDiffTime (-1)@ will not perfectly invert a duration, due to variable month lengths.
118scaleCalendarDiffTime :: Integer -> CalendarDiffTime -> CalendarDiffTime
119scaleCalendarDiffTime k (CalendarDiffTime m d) = CalendarDiffTime (k * m) (fromInteger k * d)
120#endif
121
122-------------------------------------------------------------------------------
123-- LocalTime
124-------------------------------------------------------------------------------
125
126#if !MIN_VERSION_time(1,9,0)
127
128-- | addLocalTime a b = a + b
129addLocalTime :: NominalDiffTime -> LocalTime -> LocalTime
130addLocalTime x = utcToLocalTime utc . addUTCTime x . localTimeToUTC utc
131
132-- | diffLocalTime a b = a - b
133diffLocalTime :: LocalTime -> LocalTime -> NominalDiffTime
134diffLocalTime a b = diffUTCTime (localTimeToUTC utc a) (localTimeToUTC utc b)
135
136#endif
137