1module Data.Time.Calendar.CalendarDiffDays
2    (
3        -- * Calendar Duration
4        module Data.Time.Calendar.CalendarDiffDays
5    ) where
6
7#if MIN_VERSION_base(4,8,0)
8#else
9import Data.Monoid
10#endif
11#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,11,0)
12import Data.Semigroup hiding (option)
13#endif
14import Data.Typeable
15import Data.Data
16
17data CalendarDiffDays = CalendarDiffDays
18    { cdMonths :: Integer
19    , cdDays :: Integer
20    } deriving (Eq,
21    Data
22#if __GLASGOW_HASKELL__ >= 802
23    -- ^ @since 1.9.2
24#endif
25    ,Typeable
26#if __GLASGOW_HASKELL__ >= 802
27    -- ^ @since 1.9.2
28#endif
29    )
30
31#if MIN_VERSION_base(4,9,0)
32-- | Additive
33instance Semigroup CalendarDiffDays where
34    CalendarDiffDays m1 d1 <> CalendarDiffDays m2 d2 = CalendarDiffDays (m1 + m2) (d1 + d2)
35#endif
36
37-- | Additive
38instance Monoid CalendarDiffDays where
39    mempty = CalendarDiffDays 0 0
40#if MIN_VERSION_base(4,9,0)
41    mappend = (<>)
42#else
43    mappend (CalendarDiffDays m1 d1) (CalendarDiffDays m2 d2) = CalendarDiffDays (m1 + m2) (d1 + d2)
44#endif
45
46instance Show CalendarDiffDays where
47    show (CalendarDiffDays m d) = "P" ++ show m ++ "M" ++ show d ++ "D"
48
49calendarDay :: CalendarDiffDays
50calendarDay = CalendarDiffDays 0 1
51
52calendarWeek :: CalendarDiffDays
53calendarWeek = CalendarDiffDays 0 7
54
55calendarMonth :: CalendarDiffDays
56calendarMonth = CalendarDiffDays 1 0
57
58calendarYear :: CalendarDiffDays
59calendarYear = CalendarDiffDays 12 0
60
61-- | Scale by a factor. Note that @scaleCalendarDiffDays (-1)@ will not perfectly invert a duration, due to variable month lengths.
62scaleCalendarDiffDays :: Integer -> CalendarDiffDays -> CalendarDiffDays
63scaleCalendarDiffDays k (CalendarDiffDays m d) = CalendarDiffDays (k * m) (k * d)
64